約 5,871,340 件
https://w.atwiki.jp/autohotkey_v2/pages/16.html
バージョン2.0.2 © 2014 Steve Gray、Chris Mallett、部分 © AutoIt チームおよびその他多数 ソフトウェア ライセンス GNU 一般公衆利用許諾契約書 クイックリファレンス 入門: プログラムの使い方 チュートリアル サンプルコードの実行方法 ホットキーの書き方 キーストロークの送信方法 プログラムの実行方法 ウィンドウの管理方法 tidbit による初心者向けチュートリアル AutoHotkey をサポートするテキスト エディター よくある質問 スクリプト 概念と規約 知っておくべきさまざまなことの説明。 スクリプト言語 スクリプトの書き方。 その他のトピック 組み込み関数のリスト 変数と式 関数の使い方 オブジェクト インタラクティブなデバッグ キーボードとマウス ホットキー (マウス、ジョイスティック、およびキーボード ショートカット) ホットストリングと自動置換 キーとボタンの再マッピング キー、マウス ボタン、およびジョイスティック コントロールのリスト その他: DllCall 正規表現のクイック リファレンス 謝辞 1999 年に AutoIt v2 をフリー ソフトウェアとしてリリースしてくださった Jonathan Bennett に特別な感謝を捧げます。彼の寛大さは、私自身や世界中の多くの人々にインスピレーションを与え、時間を節約してくれました。さらに、AutoIt v2 コマンド セットに対する AutoHotkey の拡張機能の多く、ならびに Window Spy および古いスクリプト コンパイラは、AutoIt v3 ソース コードから直接適用されました。Jon と他の AutoIt の作成者にも感謝します。 最後に、AutoHotkey は、これらの他の個人なしでは今日のようにはなりませんでした。 〜クリス・マレット https //www.autohotkey.com/docs/v2/index.htm
https://w.atwiki.jp/autohotkey_v2/
バージョン2.0.2 © 2014 Steve Gray、Chris Mallett、部分 © AutoIt チームおよびその他多数 ソフトウェア ライセンス GNU 一般公衆利用許諾契約書 クイックリファレンス 入門: プログラムの使い方 チュートリアル ・サンプルコードの実行方法 ・ホットキーの書き方 ・キーストロークの送信方法 ・プログラムの実行方法 ・ウィンドウの管理方法 ・tidbit による初心者向けチュートリアル AutoHotkey をサポートするテキスト エディター よくある質問 スクリプト 概念と規約 知っておくべきさまざまなことの説明。 スクリプト言語 スクリプトの書き方。 その他のトピック 組み込み関数のリスト 変数と式 関数の使い方 オブジェクト インタラクティブなデバッグ キーボードとマウス ホットキー (マウス、ジョイスティック、およびキーボード ショートカット) ホットストリングと自動置換 キーとボタンの再マッピング キー、マウス ボタン、およびジョイスティック コントロールのリスト その他: DllCall 正規表現のクイック リファレンス 謝辞 1999 年に AutoIt v2 をフリー ソフトウェアとしてリリースしてくださった Jonathan Bennett に特別な感謝を捧げます。彼の寛大さは、私自身や世界中の多くの人々にインスピレーションを与え、時間を節約してくれました。さらに、AutoIt v2 コマンド セットに対する AutoHotkey の拡張機能の多く、ならびに Window Spy および古いスクリプト コンパイラは、AutoIt v3 ソース コードから直接適用されました。Jon と他の AutoIt の作成者にも感謝します。 最後に、AutoHotkey は、これらの他の個人なしでは今日のようにはなりませんでした。 〜クリス・マレット
https://w.atwiki.jp/autohotkey_v2/pages/14.html
この文書は、コードよりも説明に重点を置いて、AutoHotkeyで使用されるいくつかの一般的な概念と慣習をカバーしています。読者はスクリプトやプログラミングの予備知識を持っていることは想定されていませんが、新しい用語を学ぶ準備はしておく必要があります。 構文に関するより具体的な詳細については、「スクリプト言語」を参照してください。 目次 値 文字列 数字 ブール値 nothing オブジェクト オブジェクト・プロトコル 変数 未初期化の変数 組み込み変数 環境変数 変数参照 (VarRef) キャッシング 関数 メソッド 制御フロー 詳細 文字列エンコーディング 純粋数 名前 オブジェクト参照 値 値とは、単にプログラム内の情報の一部です。例えば、送信するキーや実行するプログラムの名前、ホットキーが押された回数、アクティブにするウィンドウのタイトルなど、プログラムまたはスクリプト内で何らかの意味を持つものです。 AutoHotkeyは、これらのタイプの値をサポートしています。 文字列(テキスト) 数字(整数、浮動小数点数) 対象物 Type関数は、値の型を決定するために使用することができます。 その他、関連する概念もあります。 boolean nothing 文字列 文字列は単なるテキストです。各文字列は実際には文字の並びや列であるが、1つの実体として扱うことができる。文字列の長さは、シーケンス内の文字の数であり、文字列内の文字の位置は、単にその文字の連番です。AutoHotkeyの慣例では、最初の文字が位置1になります。 数値文字列。数字の文字列(またはサポートされているその他の数字フォーマット)は、数学演算や比較で必要とされる場合、自動的に数字として解釈されます。 スクリプト内でリテラルテキストをどのように書くべきかは、文脈によって異なります。例えば、式では、文字列は引用符で囲む必要があります。ディレクティブ(#HotIfを除く)と自動置換ホットストリングでは、引用符は必要ありません。 文字列の動作の詳細については、「文字列のエンコード」を参照してください。 数字 AutoHotkey は次の数値形式をサポートしています。 123、00123または などの 10 進整数。-1 0x7B、0x007Bまたは などの 16 進数の整数。-0x1 3.14159のような10進数の浮動小数点数。 ドキュメントに記載されている場合を除き、16 進数は接頭辞0xまたはを使用する必要があります。このプレフィックスは、または記号が存在する場合はその後、先頭のゼロの前に0X記述する必要があります。たとえば、有効ですが、そうではありません。+-0x001000x1 小数点で書かれた数値は、小数部分がゼロであっても、常に浮動小数点と見なされます。たとえば、42と は42.0通常交換可能ですが、常にではありません。科学表記法も認識されますが (例 1.0e4and )、小数点がなくても常に浮動小数点数が生成されます。-2.1E-4 ユーザーの地域設定でコンマが指定されている場合でも、小数点記号は常にドットです。 数値が文字列に変換されると、10 進数として書式設定されます。浮動小数点数は完全な精度でフォーマットされます (ただし、冗長な後続ゼロは破棄されます)。これにより、場合によっては不正確さが明らかになることがあります。Format関数を使用して、数値文字列を別の形式で生成します。浮動小数点数は、Round関数を使用してフォーマットすることもできます。 数値の範囲と精度の詳細については、純粋な数値を参照してください。 ブール値 ブーリアン値は、真または偽のいずれかになります。ブール値は、式の真偽など、2つの可能性を持つものを表現するのに使われます。例えば、式(x = y)は、xがyより小さいか等しい場合に真となります。ブーリアン値は、イエスかノー、オンかオフ、ダウンかアップ(GetKeyStateなど)などを表すこともできます。 AutoHotkeyには特定のブーリアン型がないため、0という整数値でfalseを、1という整数値でtrueを表現します。値が真か偽のどちらかであることが要求される場合、空白またはゼロの値は偽とみなされ、その他の値はすべて真とみなされます(オブジェクトは常に真とみなされます)。 trueとfalseという単語は、1と0を含む組み込み変数です。 nothing AutoHotkeyには、他の言語で見られるような、何もない、null、nil、undefinedを一意に表す値がありません。 Null」または「undefined」値を生成する代わりに、値がない変数、プロパティ、配列要素、またはマップアイテムを読み込もうとすると、UnsetErrorが投げられます。これにより、NULL値が暗黙のうちにコードに伝搬することを許可した場合よりも、より簡単にエラーを特定することができます。こちらも参照してください。未初期化変数」も参照してください。 関数のオプションのパラメータは、関数が呼び出されたときに省略することができます。この場合、関数は動作を変更したり、デフォルト値を使用したりします。パラメータを省略するには、通常、コードから文字通り省略しますが、unsetキーワードを使用して明示的または条件付きで省略することも可能です。この特別なシグナルは、maybe演算子(var?)を使って明示的にのみ伝達することができます。unsetパラメータは、関数が実行される前に自動的にそのデフォルト値(もしあれば)を受け取ります。 主に歴史的な理由から、他の言語で null や undefined 値が使われるような場所、例えば戻り値が明示されていない関数では、空文字列が使われることがあります。 変数やパラメータが「空」または「ブランク」と呼ばれる場合は、通常、空文字列(長さがゼロの文字列)を意味します。これは、パラメータを省略することとは異なりますが、場合によっては同じ効果が得られるかもしれません。 オブジェクト オブジェクトは、 AutoHotkey の複合または抽象データ型です。オブジェクトは、任意の数のプロパティ(取得または設定可能) とメソッド(呼び出し可能)で構成できます。各プロパティまたはメソッドの名前と効果は、特定のオブジェクトまたはオブジェクトの種類によって異なります。 オブジェクトには次の属性があります。 オブジェクトは含まれていません。それらは参照されます。たとえば、alpha = []新しい配列を作成し、参照をalphaに格納します。bravo = alpha(オブジェクトではなく) への参照をコピーするbravoため、両方が同じオブジェクトを参照します。配列または変数がオブジェクトを含むと言われている場合、実際に含まれているのはオブジェクトへの参照です。 2 つのオブジェクト参照は、同じオブジェクトを参照している場合にのみ比較されます。 オブジェクトは、if obj, !obj, obj ? x y のように、ブール値が要求される場合は常に真とみなされます。 各オブジェクトは固有のアドレス(メモリ上の位置)を持っており、ObjPtr関数で取得することができますが、通常は直接使用されることはありません。このアドレスは、オブジェクトを一意に識別しますが、オブジェクトが解放されるまでの間だけです。 オブジェクトが想定外の文脈で使用された場合、空文字列として扱われることがあります。例えば、MsgBox(myObject)は、空のMsgBoxを表示します。それ以外の場合は、TypeErrorが投げられるかもしれません(将来的には、これが標準になるはずです)。 注:Objectから派生したすべてのオブジェクトは、さらに共有の動作、プロパティ、メソッドを持ちます。 オブジェクトの使われ方として、以下のようなものがあります。 アイテムや要素のコレクションを格納する。例えば、Arrayはアイテムのシーケンスを含み、Mapはキーと値を関連付ける。オブジェクトを使用すると、値のグループを1つの値として扱ったり、1つの変数に代入したり、関数に渡したり、関数から返したりすることができます。 現実的または概念的なものを表現すること。例えば、画面上の位置をXとYのプロパティで表し、アドレス帳の連絡先をName、PhoneNumber、EmailAddressなどで表します。オブジェクトは、他のオブジェクトと組み合わせることで、より複雑な情報の集合を表現するために使用することができます。 サービスやサービスの集合をカプセル化することで、スクリプトの他の部分が、そのタスクの実行方法ではなく、タスクに集中できるようにします。例えば、Fileオブジェクトは、ファイルからデータを読み取ったり、ファイルにデータを書き込んだりするメソッドを提供します。ファイルに情報を書き込むスクリプト関数が、Fileオブジェクトをパラメータとして受け取った場合、ファイルがどのように開かれたかを知る必要はありません。同じ関数を使用して、TCP/IPソケットやWebSocketなどの他のターゲットに情報を書き込むことができます(ユーザー定義オブジェクトを使用)。 上記の組み合わせ。例えば、GUIはGUIウィンドウを表し、スクリプトにグラフィカルユーザーインターフェースを作成、表示する手段を提供します。コントロールのコレクションを含み、タイトルやFocusedCtrlなどのプロパティによってウィンドウに関する情報を提供します。 オブジェクト(特にクラス)を適切に使用することで、モジュール化され再利用可能なコードを作成することができます。モジュール化されたコードは、通常、テスト、理解、保守が容易です。例えば、あるコードのセクションを改良したり変更したりする際に、他のセクションの詳細を知る必要がなく、またそのセクションに対応する変更を加える必要もありません。再利用可能なコードは、同じまたは類似のタスクのコードを何度も書いたりテストしたりする必要がないため、時間を節約することができます。 オブジェクト・プロトコル このセクションは、後のセクションでカバーされるこれらの概念に基づいています:変数、関数。 オブジェクトは、メッセージパッシングの原理で動作します。オブジェクトのコードや変数が実際にどこにあるかはわからないので、「give me foo」や「go do bar」のようにオブジェクトにメッセージを渡し、オブジェクトがそのメッセージに応答するのを頼りにする必要があります。AutoHotkeyのオブジェクトは、以下の基本的なメッセージをサポートしています。 プロパティを取得します。 プロパティを設定します( =で示されます)。 メソッドを呼び出す、()で示される。 プロパティは、設定や取得が可能なオブジェクトのいくつかの側面です。例えば、ArrayにはLengthプロパティがあり、これは配列の要素数に対応する。プロパティを定義すると、そのプロパティはどんな意味でも持つことができます。一般的に、プロパティは変数のように機能しますが、その値は必要に応じて計算され、実際にはどこにも保存されないかもしれません。 各メッセージには以下の内容が含まれており、通常はプロパティまたはメソッドが呼び出される場所に書かれています。 プロパティまたはメソッドの名前。 プロパティまたはメソッドの名前。どのようなアクションが実行されるか、値がどのように保存されるか、またはどの値が返されるかに影響を与える可能性のあるゼロ個以上のパラメータ。例えば、プロパティは、配列のインデックスやキーを取ることがあります。 例えば、次のようなものです。 myObj.methodName(arg1) value = myObj.propertyName[arg1] オブジェクトにはデフォルトのプロパティもあり、プロパティ名なしで角括弧を使用すると、このプロパティが呼び出されます。例えば、次のようなものです。 value = myObj[arg1] 一般にSetは代入と同じ意味を持つので、同じ演算子を使います。 myObj.name = value myObj.name[arg1, arg2, ..., argN] = value myObj[arg1, arg2, ..., argN] = value 変数 変数では、名前を値のプレースホルダーとして使用することができます。その値は、スクリプトの実行中に繰り返し変更される可能性があります。例えば、ホットキーの場合、変数press_countを使って押された回数をカウントし、press_countが3の倍数のとき(3回押すごとに)別のキーを送信することができます。一度しか値が割り当てられない変数でも、役に立つことがあります。例えば、WebBrowserTitleという変数を使えば、好みのWebブラウザを変更したり、ソフトウェアのアップデートでタイトルやウィンドウクラスが変わったりしたときに、コードを更新しやすくすることができます。 AutoHotkeyでは、変数は単に使用することで作成されます。各変数は永久に単一のデータ型に制限されることはなく、代わりに文字列、数値、オブジェクトなど、任意の型の値を保持することができます。値が割り当てられていない変数を読もうとするとエラーとみなされるので、変数を初期化することは重要です。 変数には、主に3つの側面があります。 変数の名前。 変数名 変数の値 変数名には一定の制限があり、詳細は「名前」を参照してください。要するに、ASCII文字(大文字小文字を区別しない)、数字、アンダースコアからなる名前にこだわるのが最も安全であり、数字から始まる名前は使わないようにしましょう。 変数名にはスコープがあり、コード内のどこでその名前を使用してその変数を参照できるか、言い換えれば、その変数が見えるかどうかを定義します。ある変数が与えられたスコープ内で見えない場合、同じ名前で別の変数を参照することができます。両方の変数が同時に存在することもあるが、スクリプトの各部分で見えるのは1つだけである。グローバル変数は、「グローバルスコープ」(つまり関数の外側)で見ることができ、デフォルトで関数から読み取ることができますが、関数内で値を割り当てる場合は宣言する必要があります。ローカル変数は、それを作成した関数の内部でのみ見ることができます。 変数は、値を格納する容器または格納場所と考えることができるので、ドキュメントでは、変数の値を変数の中身と呼ぶことがよくあります。変数x =42の場合、変数xの値として42という数字がある、あるいはxの値は42である、とも言えます。 注意しなければならないのは、変数とその値は同じものではないということです。例えば、「myArrayは配列である」と言うかもしれませんが、本当の意味は「myArrayは配列への参照を含む変数である」ということです。しかし、「myArray」は単なる変数名であり、配列オブジェクトはその名前を知らないので、さまざまな変数(したがって多くの名前)で参照される可能性があります。 未初期化の変数 変数を初期化するとは、その変数に開始値を割り当てることである。まだ値が割り当てられていない変数は、未初期化(略して未設定)です。初期化されていない変数を読み込もうとすると、エラーとみなされます。このため、名前の間違えや代入のし忘れなどのエラーを検出することができます。 IsSetは、グローバル変数やスタティック変数の初回使用時の初期化など、変数が初期化されているかどうかを判断するために使用できます。 変数の設定を解除するには、直接代入( =)とunsetキーワード、またはmaybe(var?)演算子を組み合わせます。例えば、以下のようになります。Var = unset, Var1 = (Var2?). or-maybe演算子(??)は、変数に値がない場合にデフォルト値を提供するために使用することができます。例えば、MyVar ? "Default "は、IsSet(MyVar) ?と同等です。MyVar "Default "と同じです。 組み込み変数 プログラムには便利な変数が多数組み込まれており、どのスクリプトからも参照することができます。これらの変数は、注意書きがある場合を除き、読み取り専用です。つまり、スクリプトで直接内容を変更することはできません。慣習上、これらの変数のほとんどは接頭辞 A_ で始まります。 A_KeyDelayやA_TitleMatchModeなどの一部の変数は、スクリプトの動作を制御する設定を表し、各スレッドに対して別々の値を保持します。これにより、新しいスレッドで起動したサブルーチン(ホットキー、メニュー、タイマーなど)が、他のスレッドに影響を与えずに設定を変更することができます。 特殊な変数の中には、定期的に更新されるのではなく、スクリプトがその変数を参照するたびに値が取得されたり計算されたりするものがあります。例えば、A_Clipboardはクリップボードの現在の内容をテキストとして取得し、A_TimeSinceThisHotkeyはホットキーが押されてから経過したミリ秒数を計算する。 関連:組み込み変数の一覧。 環境変数 環境変数は、オペレーティングシステムによって管理されています。コマンドプロンプトでSETと入力してEnterを押すと、環境変数の一覧が表示されます。 スクリプトは、EnvSetを使用して新しい環境変数を作成したり、既存の環境変数の内容を変更したりすることができます。このような追加や変更は、システムの他の部分からは見えません。しかし、スクリプトがRunまたはRunWaitを呼び出して起動したプログラムやスクリプトは、通常、親スクリプトの環境変数のコピーを引き継ぎます。 環境変数を取得するには、EnvGetを使用します。たとえば、次のようになります。 Path = EnvGet( PATH ) 変数参照(VarRef) 式中では、代入や参照演算子( )の対象でない限り、各変数参照はその内容に自動的に解決されます。つまり、myFunction(myVar)を呼び出すと、myVarの値がmyFunctionに渡され、変数そのものは渡されません。すると、関数はmyVarと同じ値を持つ独自のローカル変数(パラメータ)を持つことになるが、myVarに新しい値を代入することはできない。要するに、パラメータは値で渡されるのです。 参照演算子( )は、変数を値のように扱うことができます。 myVarはVarRefを生成し、他の変数やプロパティへの代入、配列への挿入、関数への受け渡し、関数からの戻り値など、他の値と同様に使用することができます。VarRefは、元のターゲット変数に割り当てたり、それを再参照することでその値を取得するために使用することができます。 関数のパラメータは、パラメータ名の前にアンパサンド( )を付けることでByRefとして宣言することができ、便利です。この場合、呼び出し側ではVarRefを渡す必要がありますが、関数自身はパラメータを参照するだけで(パーセント記号なしで)VarRefを「参照解除」することが可能です。 Path = EnvGet( PATH )class VarRef extends Any VarRef クラスには現在、定義済みのメソッドやプロパティはありませんが、value is VarRef を使用すると、値が VarRef であるかどうかをテストすることが可能です。 VarRef が COM メソッドのパラメーターとして使用される場合、オブジェクト自体は渡されません。代わりに、その値は一時的な VARIANT にコピーされ、それはバリアント型 VT_BYREF|VT_VARIANT を使用して渡されます。メソッドが戻ると、新しい値がVarRefに割り当てられます。 キャッシング 通常、変数は1つの値を保持し、その値は明確な型(文字列、数値、オブジェクト)を持っていると考えられていますが、AutoHotkeyでは、「値は" myNumber」や「MsgBox myNumber」などの場合、数値と文字列を自動的に変換しています。これらの変換は非常に頻繁に行われるため、数値を含む変数が文字列に変換されるたびに、その結果が変数にキャッシュされます。 現在、AutoHotkey v2では、純粋な数値を変数に代入するときだけキャッシュし、読み込むときはキャッシュしません。これにより、文字列と純粋な数値を区別する機能が維持されます(Type関数や、COMオブジェクトに値を渡す場合など)。 関連 変数:基本的な使い方と例。 変数容量とメモリ:制限事項の詳細。 関数 関数とは、スクリプトが何かを行うための基本的な手段です。 関数は、さまざまな目的を持つことができます。単純な計算を行うだけの関数もあれば、ウィンドウを移動させるなど、すぐに目に見える効果をもたらす関数もあります。AutoHotkeyの強みの1つは、スクリプトがいくつかの関数を呼び出すだけで、他のプログラムを自動化したり、他の多くの一般的なタスクを実行したりすることが簡単にできることです。例については、関数リストを参照してください。 この文書では、経験のない人にはわからないような方法で、いくつかの一般的な単語が使用されています。以下に、関数に関連して頻繁に使用される単語やフレーズをいくつか紹介します。 関数を呼び出す 関数を呼び出すと、プログラムはその関数を呼び出し、実行し、評価する。つまり、関数呼び出しは、一時的にスクリプトから関数に制御を移します。関数が目的を果たすと、制御をスクリプトに戻します。言い換えれば、関数呼び出しに続くコードは、関数が完了するまで実行されません。 しかし、時には、その効果がユーザーに伝わる前に関数が完了することがあります。例えば、Send関数はキーストロークを送信しますが、キーストロークが目的地に到達して意図した効果をもたらす前に戻ることがあります。 パラメータ 通常、関数は、操作方法や操作対象を指示するパラメータを受け取ります。各パラメーターは、文字列や数値などの値です。例えば、WinMoveはウィンドウを移動させるので、どのウィンドウをどこに移動させるかをパラメータで指定します。パラメータは、引数とも呼ばれます。一般的な略語としては、paramやargがあります。 パラメータを渡す パラメータは関数に渡されます。つまり、関数が呼び出されたときに、関数の各パラメータに対して値が指定されます。例えば、GetKeyStateにキーの名前を渡すと、そのキーが押されているかどうかを判断することができます。 コマンド 関数呼び出しは、プログラムに特定の動作をさせる場合など、コマンドと呼ばれることもあります。(歴史的な理由から、コマンドは、括弧が省略され、戻り値が破棄される、特定のスタイルの関数呼び出しを指す場合があります。しかし、これは厳密には関数呼び出し文である)。 関数は通常、パラメータを特定の順序で記述することを想定しているので、各パラメータの値の意味は、カンマで区切られたパラメータリストの中での位置によって決まります。パラメータによっては省略できるものもあり、その場合はパラメータを空白にすることができますが、それに続くカンマは、残りのすべてのパラメータも省略する場合にのみ省略することができます。たとえば、ControlSendの構文は次のとおりです。 ControlSend Keys[, Control, WinTitle, WinText, ExcludeTitle, ExcludeText] 角括弧は、囲んだパラメータがオプションであることを意味します(括弧自体は実際のコードに表示されません)。ただし、通常はターゲットウィンドウを指定する必要があります。例えば ControlSend ^{Home} , Edit1 , A ; Correct. Control is specified. ControlSend ^{Home} , A ; Incorrect Parameters are mismatched. ControlSend ^{Home} ,, A ; Correct. Control is omitted. メソッド メソッドは、特定のオブジェクトやオブジェクトの種類に関連付けられた関数である。メソッドを呼び出すには、オブジェクトとメソッド名を指定する必要があります。メソッド名は関数を一意に特定するものではなく、メソッド呼び出しが試みられたときに何が起こるかはオブジェクトに依存する。例えば、x.Show()は、xが何であるかによって、メニューを表示したり、GUIを表示したり、エラーを発生させたり、何か他のことをしたりするかもしれない。つまり、メソッドコールは単にオブジェクトにメッセージを渡し、何かをするように指示するものです。詳しくは、「オブジェクトのプロトコル」と「オブジェクトの演算子」を参照してください。 制御フロー 制御フローとは、個々のステートメントが実行される順序のことです。通常、ステートメントは上から下へ順番に実行されますが、制御フローステートメントでは、ステートメントを繰り返し実行したり、特定の条件が満たされた場合にのみ実行するように指定することで、これを上書きすることができます。 ステートメント ステートメントとは、簡単に言えば、実行すべき何らかのアクションを表現する、言語の最小の独立した要素のことです。AutoHotkeyでは、ステートメントには、代入、関数呼び出し、その他の式が含まれます。ただし、ディレクティブ、ダブルコロンのホットキーとホットストリングタグ、割り当てのない宣言はステートメントではなく、プログラムが最初に起動したとき、スクリプトが実行される前に処理されます。 実行する 実行する、実行する、評価する、実行に移す、など。Executeは、基本的にノンプログラミングの言葉と同じ意味です。 ボディ 制御フロー文の本文は、その文が適用される文または文のグループです。例えば、if文の本体は、特定の条件が満たされた場合にのみ実行される。 例えば、次のような簡単な手順を考えてみましょう。 メモ帳を開く メモ帳が画面に表示されるのを待つ "ハロー、ワールド!"と入力する 一度に1つのステップを踏んで、そのステップが終わると次のステップに進むのです。これと同じように、プログラムやスクリプトの制御も、ある文から次の文へと流れていくのが普通です。しかし、既存のメモ帳に入力する場合はどうでしょうか。次のような手順で考えてみましょう。 1.メモ帳が起動していない場合 1.メモ帳が起動していない場合:メモ帳を開く 2.メモ帳が画面に表示されるのを待つ 2.それ以外の場合 1.メモ帳を起動する 3."ハロー、ワールド!"と入力する。 つまり、メモ帳を開くか、メモ帳を起動するかは、すでに起動しているかどうかによります。#1.は条件文であり、if文とも呼ばれる。つまり、ある条件を満たした場合にのみ、その本体(#1.1~#1.2)を実行する。#2.はelse文で、前のif文(#1)の条件が満たされない場合にのみ、その本体(#2.1)を実行する。条件によって、制御は次の2つのうちどちらかに流れます。#1(真の場合)→#1.1→#1.2→#3、または#1(偽の場合)→#2(else)→#2.1→#3です。 上記の命令は、以下のようなコードに変換することができます。 if (not WinExist( ahk_class Notepad )) { Run Notepad WinWait ahk_class Notepad } else WinActivate ahk_class Notepad Send Hello, world{!} 文書による指示では、インデントと番号を使ってステートメントをグループ化しました。スクリプトの動作は少し異なります。インデントはコードを読みやすくしますが、AutoHotkeyでは、ステートメントのグループ化には影響しません。その代わり、上図のように中括弧で囲むことでステートメントをグループ化します。これをブロックと呼びます。 構文についての詳細、つまりAutoHotkeyで制御フロー文を書く、または認識する方法については、「制御フロー」を参照してください。 詳細 文字列のエンコード 文字列の各文字は、その序数(文字コード)と呼ばれる数字で表現されます。例えば、"Abc "という値は次のように表されます。 A b c 65 98 99 0 エンコーディング 文字列のエンコーディングは、記号が序数に、序数がバイトにどのようにマッピングされるかを定義します。多くの異なるエンコーディングがありますが、AutoHotkeyでサポートされているものはすべてASCIIをサブセットとして含んでいるので、文字コード0から127は常に同じ意味を持っています。例えば、 A は常に文字コード65を持ちます。 Null-termination (ヌル文字) 各文字列は「ヌル文字」で終了します。言い換えれば、序列値がゼロの文字が文字列の終わりを示すことになります。文字列の長さは、ヌル終端文字の位置から推測できますが、AutoHotkeyは、パフォーマンスのため、また文字列の長さの範囲内でヌル文字を許可するために、長さも保存します。 注:ヌル終端処理に依存しているため、多くの組み込み関数とほとんどの式演算子はヌル文字が埋め込まれた文字列をサポートしておらず、代わりに最初のヌル文字までしか読みません。しかし、このような文字列の基本的な操作は可能です。例えば、連結、==、!==、Chr(0)、StrLen、SubStr、代入、パラメータ値、戻り値などです。 ネイティブエンコーディング。AutoHotkeyは様々なエンコーディングのテキストを扱う方法を提供していますが、組み込み関数、そしてある程度言語自体が、すべて文字列値がある特定のエンコーディングであることを前提としています。これはネイティブエンコーディングと呼ばれるものです。ネイティブエンコーディングは、AutoHotkeyのバージョンに依存します。 AutoHotkeyのUnicodeバージョンはUTF-16を使用します。UTF-16文字列の最小要素は2バイト(16ビット)です。0から65535(U+FFFF)の範囲のUnicode文字は、同じ値の単一の16ビットコードユニットで表され、65536(U+10000)から1114111(U+10FFFF)の範囲の文字は、サロゲートペアで表されます(つまり、0xD800から0xDFFFまでのちょうど二つの16ビットコードユニットです。(サロゲートペアの詳しい説明やエンコード、デコードの方法については、インターネットを検索してください)。 AutoHotkeyのANSIバージョンは、システムのロケールまたは「非Unicodeプログラム用の言語」システム設定に依存する、システムのデフォルトANSIコードページを使用します。ANSI文字列の最小の要素は1バイトです。ただし、コードページによっては、複数バイトのシーケンスで表現される文字が含まれています(これらは常に非ASCII文字です)。 注:AutoHotkey v2はネイティブでUnicodeを使用し、ANSIバージョンはありません。 文字。一般に、この文書の他の部分では、文字列の最小単位を意味する用語「文字」を使用しています。ANSI文字列ではバイト、Unicode(UTF-16)文字列では16ビットコードユニットです。実用的な理由から、文字列の長さや文字列内の位置は、完全なUnicode文字でなくても、これらの固定サイズの単位を数えることによって測定されます。 FileRead、FileAppend、FileOpen、Fileオブジェクトは、特定のエンコーディングを持つファイル内のテキストの読み書きの方法を提供します。 StrGetとStrPut関数は、ネイティブエンコーディングと他の指定されたエンコーディングの間で文字列を変換するために使用することができます。しかし、これらは通常、データ構造やDllCall関数と組み合わせた場合にのみ有効です。DllCallに直接渡される文字列やDllCallから渡される文字列は、AStrやWStrのパラメータ型を使用してANSIやUTF-16に変換することができます。 AutoHotkeyのANSIバージョンとUnicodeバージョンの違いを扱うためのテクニックは、Unicode vs ANSIで見つけることができます。 純粋数 純粋数または2進数は、コンピュータのCPUが直接演算処理できる形式でメモリに保存されているものです。ほとんどの場合、AutoHotkeyは必要に応じて数値文字列と純粋数を自動的に変換し、この2つのタイプを区別することはほとんどありません。AutoHotkeyは、主に純粋な数値に2つのデータ型を使用します。 64ビット符号付き整数(int64)。 64ビットバイナリ浮動小数点数(IEEE 754国際標準のdoubleまたはbinary64フォーマット)。 つまり、スクリプトは以下の制限に影響される。 つまり、-9223372036854775808(-0x800000000000、または-263)から9223372036854775807(0x7FFFFFFFFF、または263-1)の範囲内でなければならない。式中の整数定数がこの範囲外の場合、下位64ビットのみが使用されます(値は切り捨てられます)。より大きな値を文字列に含めることもできますが、文字列を数値に変換しようとすると(数学の演算で使用するなど)、同様に切り捨てられることになります。 浮動小数点数は、一般に15桁の精度をサポートします。 注:2進浮動小数点形式では正確に表現できない10進数の分数があるため、表現可能な最も近い数値に丸められます。そのため、最も近い数値に丸められ、予想外の結果になることがあります。例えば MsgBox 0.1 + 0 ; 0.10000000000000001 MsgBox 0.1 + 0.2 ; 0.30000000000000004 MsgBox 0.3 + 0 ; 0.29999999999999999 MsgBox 0.1 + 0.2 = 0.3 ; 0 (not equal) その対策として、直接の比較を避け、代わりに違いを比較することがあります。例えば MsgBox Abs((0.1 + 0.2) - (0.3)) 0.0000000000000001 もう一つの方法は、文字列に変換するなどして、比較の前に明示的に丸めを適用することである。精度を指定しながらこれを行うには、一般に2つの方法があり、どちらも以下に示すとおりです。 MsgBox Round(0.1 + 0.2, 15) = Format( { .15f} , 0.3) 名称 AutoHotkeyでは、変数、関数、ウィンドウグループ、クラス、プロパティ、メソッドなど、さまざまなものの命名に、同じルールを使用しています。そのルールは以下の通りです。 大文字と小文字を区別する。ASCII 文字の場合はなし。例えば、CurrentDateはcurrentdateと同じです。しかし、 Ä のような大文字の非ASCII文字は、現在のユーザーのロケールに関係なく、小文字の対応する文字と同等とはみなされません。これは、スクリプトが複数のロケール間で一貫した動作をするのに役立ちます。 最大文字数:253文字 使用可能な文字。文字、数字、アンダースコア、非ASCII文字。ただし、1文字目は数字にできません。 予約語:as, and, contains, false, in, is, IsSet, not, or, super, true, unset. これらの単語は、将来の使用やその他の特定の目的のために予約されています。 宣言キーワードや制御フロー文の名前も、主に間違いを検出するために予約されています。これには次のようなものがあります。Break、Catch、Continue、Else、Finally、For、Global、Goto、If、Local、Loop、Return、Static、Throw、Try、Until、While。 プロパティ名、メソッド名、ウィンドウグループ名には予約語を使用することができる。 オブジェクト参照 スクリプトは、オブジェクトへの参照を通じて、間接的にのみオブジェクトと対話します。オブジェクトを作成するとき、オブジェクトはあなたがコントロールできない場所に作成され、あなたに参照が与えられます。この参照を関数に渡したり、変数や別のオブジェクトに格納したりすると、同じオブジェクトへの新しい参照が作成されます。 例えば、myObjにオブジェクトへの参照が含まれている場合、yourObj = myObjは同じオブジェクトへの新しい参照を作成する。myObj.ans = 42 のような変更は、myObj.ans と yourObj.ans の両方が同じオブジェクトを参照しているため、反映されるでしょう。しかし、myObj = Object()は変数myObjにのみ影響し、変数yourObjはまだ元のオブジェクトを参照しているわけではありません。 参照は、単に代入を使って他の値に置き換えることで解放されます。オブジェクトは、すべての参照が解放された後にのみ削除されます。オブジェクトを明示的に削除することはできませんので、試してはいけません。(ただし、オブジェクトのプロパティ、コンテンツ、関連リソース(Arrayの要素、Guiに関連するウィンドウ、Menuオブジェクトのメニューなど)は削除することができます)。 ref1 = Object() ; Create an object and store first reference ref2 = ref1 ; Create a new reference to the same object ref1 = ; Release the first reference ref2 = ; Release the second reference; object is deleted もし理解しにくければ、オブジェクトをレンタルユニットとみなしてみてください。借りるときに渡されるのは、その部屋に入るための鍵です。そして、その鍵を使って同じユニットにアクセスすることができるのですが、そのユニットを使い終わったら、すべての鍵をレンタル業者に返さなければなりません。通常、ユニットは削除されませんが、オブジェクトに保存された値が削除されると解放されるのと同じように、エージェントは、あなたが残したガラクタを削除してくれるかもしれませんね。 https //www.autohotkey.com/docs/v2/Concepts.htm#variable-references
https://w.atwiki.jp/autohotkey_v2/pages/12.html
このドキュメントでは、コードではなく説明に焦点を当てて、AutoHotkey で使用されるいくつかの一般的な概念と規則について説明します。読者は、スクリプトやプログラミングの予備知識を持っているとは想定されていませんが、新しい用語を習得する準備ができている必要があります。 構文の詳細については、Scripting Languageを参照してください。 目次 値 ストリングス 数字 ブール値 なし オブジェクト オブジェクト プロトコル 変数 初期化されていない変数 組み込み変数 環境変数 変数参照 (VarRef) キャッシング 機能 メソッド 制御フロー 詳細 文字列エンコーディング 純粋な数字 名前 オブジェクトへの参照 値 値は、プログラム内の単なる情報です。たとえば、送信するキーまたは実行するプログラムの名前、ホットキーが押された回数、アクティブにするウィンドウのタイトル、またはプログラムまたはスクリプト内で何らかの意味を持つその他のもの。 AutoHotkey は、次のタイプの値をサポートしています。 文字列(テキスト) 数値(整数および浮動小数点数) オブジェクト Type関数を使用して、値の型を判別できます。 その他の関連する概念 ブール値 なし ストリングス 文字列は単なるテキストです。各文字列は、実際には一連の文字列または文字列ですが、1 つのエンティティとして扱うことができます。文字列の長さはシーケンス内の文字数ですが、文字列内の文字の位置は単にその文字の連続番号です。AutoHotkey の慣例により、最初の文字の位置は 1 です。 数値文字列 数字の文字列 (またはサポートされているその他の数値形式) は、数学演算または比較で必要になると、自動的に数値として解釈されます。 スクリプト内でリテラル テキストをどのように記述するかは、コンテキストによって異なります。たとえば、式では、文字列を引用符で囲む必要があります。ディレクティブ (#HotIf を除く) とホットストリングの自動置換では、引用符は必要ありません。 文字列の仕組みの詳細については、文字列のエンコードを参照してください。 数字 AutoHotkey は次の数値形式をサポートしています。 123、00123または などの 10 進整数。-1 0x7B、0x007Bまたは などの 16 進数の整数。-0x1 などの 10 進浮動小数点数3.14159。 ドキュメントに記載されている場合を除き、16 進数は接頭辞0xまたはを使用する必要があります。このプレフィックスは、または記号が存在する場合はその後、先頭のゼロの前に0X記述する必要があります。たとえば、有効ですが、そうではありません。+-0x001000x1 小数点で書かれた数値は、小数部分がゼロであっても、常に浮動小数点と見なされます。たとえば、42と は42.0通常交換可能ですが、常にではありません。科学表記法も認識されますが (例 1.0e4and )、小数点がなくても常に浮動小数点数が生成されます。-2.1E-4 ユーザーの地域設定でコンマが指定されている場合でも、小数点記号は常にドットです。 数値が文字列に変換されると、10 進数として書式設定されます。浮動小数点数は完全な精度でフォーマットされます (ただし、冗長な後続ゼロは破棄されます)。これにより、場合によっては不正確さが明らかになることがあります。Format関数を使用して、数値文字列を別の形式で生成します。浮動小数点数は、Round関数を使用してフォーマットすることもできます。 数値の範囲と精度の詳細については、純粋な数値を参照してください。 ブール値 ブール値は、trueまたはfalseのいずれかです。ブール値は、式の真など、可能な状態が 2 つだけあるものを表すために使用されます。たとえば、x の値が y より小さいか等しい場合、式はtrue(x = y)です。ブール値は、yesまたはno、onまたはoff、downまたはup ( GetKeyStateなど) などを表すこともできます。 AutoHotkey には特定のブール型がないため、整数値を使用して0false を表し、1true を表します。値が true または false である必要がある場合、空白またはゼロの値は false と見なされ、他のすべての値は true と見なされます。(オブジェクトは常に true と見なされます。) trueおよび という単語は、 1 と 0 を含む組み込み変数falseです。スクリプトを読みやすくするために使用できます。 なし AutoHotkey には、他の言語に見られるような、 Nothing、null、nil、またはundefinedを一意に表す値はありません。 「null」または「未定義」の値を生成する代わりに、値を持たない変数、プロパティ、配列要素、またはマップ項目を読み取ろうとすると、UnsetError がスローされます。これにより、null 値が暗黙的にコードを介して伝播することを許可されている場合よりも、エラーをより簡単に識別できます。参照 初期化されていない変数。 関数のオプション パラメータは、関数の呼び出し時に省略できます。その場合、関数は動作を変更したり、デフォルト値を使用したりできます。パラメータは通常、文字通りコードから省略されますが、unsetキーワードを使用して明示的または条件付きで省略されることもあります。この特別なシグナルは、 maybe 演算子 ( var ? )を使用して明示的にのみ伝播できます。設定されていないパラメータは、関数が実行される前にデフォルト値 (存在する場合) を自動的に受け取ります。 主に歴史的な理由から、空の文字列は、明示的な戻り値を持たない関数など、他の言語で null または未定義の値が使用される場所で使用されることがあります。 変数またはパラメーターが「空」または「空白」であると言われている場合、それは通常、空の文字列 (長さゼロの文字列) を意味します。これは、パラメーターを省略することと同じではありませんが、場合によっては同じ結果になることがあります。 オブジェクト オブジェクトは、 AutoHotkey の複合または抽象データ型です。オブジェクトは、任意の数のプロパティ(取得または設定可能) とメソッド(呼び出し可能)で構成できます。各プロパティまたはメソッドの名前と効果は、特定のオブジェクトまたはオブジェクトの種類によって異なります。 オブジェクトには次の属性があります。 オブジェクトは含まれていません。それらは参照されます。たとえば、alpha = []新しい配列を作成し、参照をalphaに格納します。bravo = alpha(オブジェクトではなく) への参照をコピーするbravoため、両方が同じオブジェクトを参照します。配列または変数がオブジェクトを含むと言われている場合、実際に含まれているのはオブジェクトへの参照です。 2 つのオブジェクト参照は、同じオブジェクトを参照している場合にのみ比較されます。 や など、ブール値が必要な場合、オブジェクトは常にtrueと見なされます。if obj!objobj ? x y 各オブジェクトには一意のアドレス (メモリ内の場所) があり、 ObjPtr関数で取得できますが、通常は直接使用されません。このアドレスはオブジェクトを一意に識別しますが、オブジェクトが解放されるまでのみです。 オブジェクトが想定外のコンテキストで使用された場合、空の文字列として扱われることがあります。たとえば、MsgBox(myObject)空の MsgBox を示しています。それ以外の場合は、TypeError がスローされる可能性があります (これは将来標準になるはずです)。
https://w.atwiki.jp/lockerroom/pages/13.html
ActiveX.ahk /* COM操作ライブラリby 流行らせるページ管理人 Ver 3β / ActiveX(){ global IID_IDispatch =GUID("{00020400-0000-0000-C000-000000000046}") IID_IUnknown =GUID("{00000000-0000-0000-C000-000000000046}") IID_NULL =GUID("{00000000-0000-0000-0000-000000000000}") IID_IConnectionPointContainer =GUID("{B196B284-BAB4-101A-B69C-00AA00341D07}") IID_IProvideClassInfo =GUID("{B196B283-BAB4-101A-B69C-00AA00341D07}") ;IID_IProvideClassInfo2 =GUID("{A6BC3AC0-DBAA-11CE-9DE3-00AA004BB851}") LOCALE_USER_DEFAULT =DllCall("kernel32.dll¥GetUserDefaultLCID") CoInitialize() } /* ********************************** 汎用メモリ管理 ********************************** / ;メモリを確保しポインタを返す Malloc(size,flag=0x40){ return DllCall("kernel32.dll¥GlobalAlloc","UInt",flag,"UInt",size,"UInt") } ;ポインタで指定されたメモリを解放する Free(p){ DllCall("kernel32.dll¥GlobalFree",UInt,p,UInt) } /* ********************************** GUID関連 ********************************** / ;CLSID文字列からGUID構造体を生成しアドレスを得る(仮) GUID(string){ size =DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",string,"Int",-1,"UInt",0,"Int",0) wstr =Malloc((size+1)*2) DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",string,"Int",-1,"UInt",wstr,"Int",(size+1)*2) ptr =Malloc(16) DllCall("ole32.dll¥CLSIDFromString","UInt",wstr,"UInt",ptr) Free(wstr) return ptr } ;ProgID文字列からGUID構造体を生成しアドレスを得る(仮) ProgID(string){ size =DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",string,"Int",-1,"UInt",0,"Int",0) wstr =Malloc((size+1)*2) DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",string,"Int",-1,"UInt",wstr,"Int",(size+1)*2) ptr =Malloc(16) DllCall("ole32.dll¥CLSIDFromProgID","UInt",wstr,"UInt",ptr) Free(wstr) return ptr } ;GUID構造体を文字列に変換 fromGUID(ByRef guid){ ptr =Malloc(80) DllCall("ole32.dll¥StringFromGUID2","UInt",guid,"UInt",ptr,"Int",80) res =wc2mb(ptr) Free(ptr) return res } /* ********************************** Unicode関連 ********************************** / ;文字列からにUnicodeへの変換を行う ;返り値はUnicode文字列へのポインタ mb2wc(mbstr){ size =(DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",mbstr,"Int",-1,"UInt",0,"Int",0)+1)*2 wstr =Malloc(size) DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",mbstr,"Int",-1,"UInt",wstr,"Int",size) return wstr } mb2wc_ref(ByRef mbstr){ size =(DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",mbstr,"Int",-1,"UInt",0,"Int",0)+1)*2 wstr =Malloc(size) DllCall("kernel32.dll¥MultiByteToWideChar","UInt",0,"UInt",0,"Str",mbstr,"Int",-1,"UInt",wstr,"Int",size) return wstr } ;UnicodeからAnsi文字列への変換を行う ;返り値は文字列 wc2mb(wstr){ size =DllCall("kernel32.dll¥WideCharToMultiByte","UInt",0,"UInt",0,"UInt",wstr,"Int",-1,"UInt",0,"Int",0,"UInt",0,"UInt",0) VarSetCapacity(mbstr,size) DllCall("kernel32.dll¥WideCharToMultiByte","UInt",0,"UInt",0,"UInt",wstr,"Int",-1,"Str",mbstr,"Int",size,"UInt",0,"UInt",0) return mbstr } wc2mb_ref(wstr,ByRef mbstr){ size =DllCall("kernel32.dll¥WideCharToMultiByte","UInt",0,"UInt",0,"UInt",wstr,"Int",-1,"UInt",0,"Int",0,"UInt",0,"UInt",0) VarSetCapacity(mbstr,size) DllCall("kernel32.dll¥WideCharToMultiByte","UInt",0,"UInt",0,"UInt",wstr,"Int",-1,"Str",mbstr,"Int",size,"UInt",0,"UInt",0) return size } /* ********************************** COM汎用 ********************************** / CoInitialize(){ return DllCall("ole32.dll¥CoInitialize","UInt",0,"UInt") } CoUninitialize(){ return DllCall("ole32.dll¥CoUninitialize","UInt",0,"UInt") } OleInitialize(){ return DllCall("ole32.dll¥OleInitialize","UInt",0,"UInt") } OleUninitialize(){ return DllCall("ole32.dll¥OleUninitialize","UInt",0,"UInt") } CoTaskMemAlloc(size){ return DllCall("ole32.dll¥CoTaskMemAlloc","UInt",size,"UInt") } CoTaskMemFree(ptr){ return DllCall("ole32.dll¥CoTaskMemFree","UInt",ptr,"UInt") } M(ByRef ip,idx=0){ return NumGet(NumGet(ip+0)+4*idx) } QueryInterface(pObj,strIID=""){ global IID_IDispatch guid =0 if(strIID=""){ IID =IID_IDispatch }else if(StrLen(strIID)=38){ IID =GUID(strIID) }else{ IID =strIID } res =0 ErrorLevel =DllCall(M(pObj,0),"UInt",pObj,"UInt",IID,"UIntP",res) return res } AddRef(pObj){ if(pObj){ DllCall(M(pObj,1),"UInt",pObj) } return pObj } Release(pObj){ if(pObj){ return DllCall(M(pObj,2),"UInt",pObj) } } ReleaseL(p1,p2=-1,p3=-1,p4=-1,p5=-1,p6=-1,p7=-1,p8=-1,p9=-1){ format =A_FormatInteger SetFormat,Integer,D Loop,10{ if(p%A_Index%!=-1){ Release(p%A_Index%) } } SetFormat,Integer,%format% } /* ********************************** VARIANT関連 ********************************** / ;Ansi文字列をBSTR形式に変換する toBSTR(str){ oc =mb2wc(str) res =DllCall("oleaut32.dll¥SysAllocString","UInt",oc,"UInt") Free(oc) return res } ;BSTRをAnsi文字列に変換する fromBSTR(bstr){ return wc2mb(bstr) } ;BSTRを解放する(VariantClear内でやってくれるはずなので多分不要) freeBSTR(bstr,get=0){ if(get!=0){ wc2mb_ref(bstr,res) }else{ res= } DllCall("oleaut32.dll¥SysFreeString","UInt",bstr) return res } vNull(){ return 0x7FFFFFFF00000000 } vObj(obj){ return 0x7FFFFFFF00000000 | obj } ;VARIANTに変換(typeには変換したい型を指定 ;settypeを指定すると、型変換した上で、型を示す値としてsettypeで指定した型を格納する toVariant(value,variant=0,type=0x08,settype=-1){ global LOCALE_USER_DEFAULT ;格納先初期化 if(variant=0){ dest =Malloc(16) }else{ dest =variant } DllCall("oleaut32.dll¥VariantInit","UInt",dest) if(type=0x08){ if(value 32 = 0x7FFFFFFF){ if(value-0x7FFFFFFF00000000=0){ ;VT_NULL NumPut(0x01,dest+0,0,"UShort") }else{ ;VT_DISPATCH NumPut(0x09,dest+0,0,"UShort") NumPut(value - 0x7FFFFFFF00000000,dest+8,0) } }else{ ;文字列の場合 NumPut(0x08,dest+0,0,"UShort") NumPut(toBSTR(value),dest+8,0) } }else{ ;それ以外の型の場合 tmp =toVariant(value) DllCall("oleaut32.dll¥VariantChangeTypeEx","UInt",dest,"UInt",tmp,"UInt",LOCALE_USER_DEFAULT,"UShort",0,"UShort",type) if(settype!=-1){ NumPut(settype,dest+0,0,"UShort") } vFree(tmp) } return dest } ;VARIANTに格納された内容を通常のAutoHotkey変数として取得 ;rawsizeが1,2,4の場合、格納されている生の値を取得 ;rawsizeが0の場合、文字列に変換して取得 fromVariant(var,rawsize=0){ global LOCALE_USER_DEFAULT if(rawsize=0){ type =NumGet(var+0,0,"UShort") if((type=9)||(type=13)){ ;COMオブジェクト pObj =NumGet(var+8) AddRef(pObj) return pObj }else if(type 0xFF){ ;ポインタもしくは配列(暫定) return NumGet(var+8) }else{ ;VT_BSTRに変換 var2 =Malloc(16) DllCall("oleaut32.dll¥VariantInit","UInt",var2) DllCall("oleaut32.dll¥VariantChangeTypeEx","UInt",var2,"UInt",var,"UInt",LOCALE_USER_DEFAULT,"UShort",0,"UShort",0x8) ;値をAnsiに変換 wc2mb_ref(NumGet(var2+8),res) vFree(var2) return res } }else if(rawsize=1){ return NumGet(var+8,0,"UChar") }else if(rawsize=2){ return NumGet(var+8,0,"UShort") }else if(rawsize=4){ return NumGet(var+8) }else{ return fromVariant(var,0) } } ;VARIANTを解放(getに-1以外を指定すると、値を取得して返す) vFree(ByRef var,get=-1){ if(get!=-1){ res =fromVariant(var,get) }else{ res =0 } DllCall("oleaut32.dll¥VariantClear","UInt",var) Free(var) return res } /* ********************************** IDispatch用 ********************************** / ;オブジェクトを生成する CreateObject(clsid,iid="",CLSCTX=5){;CLSCTX_SERVER global IID_IDispatch if(!IID_IDispatch){ ActiveX() } guid =0 if(RegExMatch(clsid,"^¥{[¥-0-9a-fA-F]{36}¥}$")){ guid =GUID(clsid) }else{ guid =ProgID(clsid) } if(iid=""){ iid2 =IID_IDispatch }else{ iid2 =GUID(iid) } ppRes =0 el =DllCall("ole32.dll¥CoCreateInstance","UInt",guid,"UInt",0,"UInt",CLSCTX,"UInt",iid2,"UIntP",ppRes,"UInt") Free(guid) if(iid2!=IID_IDispatch){ Free(iid2) } ErrorLevel =el return ppRes } ;objが持つnameメンバのDispatchIDを得る GetDispID(ByRef obj,name){ global IID_NULL,LOCALE_USER_DEFAULT wName =mb2wc_ref(name) dispid =0 DllCall(M(obj,5),"UInt",obj,"UInt",IID_NULL,"UIntP",wName,"UInt",1,"UInt",LOCALE_USER_DEFAULT,"UIntP",dispid,"UInt") Free(wName) return dispid } ;引数からDISPPARAMSを生成 CreateParam(ByRef p1, ByRef p2, ByRef p3, ByRef p4, ByRef p5, ByRef p6, ByRef p7, ByRef p8, ByRef p9, ByRef p10){ ;引数を数える(0xFFFFFFFFFFFFFFFFの前までが与えられた引数) num =0 format =A_FormatInteger SetFormat,Integer,D Loop,10{ if(p%A_Index%=0xFFFFFFFFFFFFFFFF){ break } num++ } ;num個のVARIANTARG配列を作成 if(num=0){ pvArgs =0 }else{ pvArgs =Malloc(16*num) ptr =pvArgs+16*(num-1) ;引数をセットしていく Loop,%num%{ toVariant(p%A_Index%,ptr) ptr-=16 } } SetFormat,Integer,%format% ;DISPPARAMS作成 res =Malloc(16) NumPut(pvArgs,res+0) NumPut(num,res+8) return res } ;DISPPARAMSを解放 FreeParam(ByRef params){ num =NumGet(params+8) pvArgs =NumGet(params+0) pvNArgs =NumGet(params+4) ;VARIANTARGの解放処理 ptr =pvArgs Loop,%num%{ vFree(ptr) ptr+=16 } ;VARIANTARG自体の解放 Free(ptr) ;rgdispidNamedArgsの解放 if(pvNArgs!=0){ Free(pvNArgs) } ;本体メモリ解放 Free(params) } Invoke(ByRef pObj,ByRef dispid,mode,ByRef params){ global IID_NULL,LOCALE_USER_DEFAULT pvRes =Malloc(16) DllCall("oleaut32.dll¥VariantInit",UInt,pvRes) DllCall(M(pObj,6),UInt,pObj,UInt,dispid,UInt,IID_NULL,UInt,LOCALE_USER_DEFAULT,UInt,mode,UInt,params,UInt,pvRes,UInt,0,UInt,0,UInt) return pvRes } inv(obj,name,p1=0xFFFFFFFFFFFFFFFF,p2=0xFFFFFFFFFFFFFFFF,p3=0xFFFFFFFFFFFFFFFF,p4=0xFFFFFFFFFFFFFFFF,p5=0xFFFFFFFFFFFFFFFF,p6=0xFFFFFFFFFFFFFFFF,p7=0xFFFFFFFFFFFFFFFF,p8=0xFFFFFFFFFFFFFFFF,p9=0xFFFFFFFFFFFFFFFF,p10=0xFFFFFFFFFFFFFFFF){ if((dispid =GetDispID(obj,name))!=0){ params =CreateParam(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) pvRes =Invoke(obj,dispid,1,params) FreeParam(params) return vFree(pvRes,0) } } gp(obj,name,p1=0xFFFFFFFFFFFFFFFF,p2=0xFFFFFFFFFFFFFFFF,p3=0xFFFFFFFFFFFFFFFF,p4=0xFFFFFFFFFFFFFFFF,p5=0xFFFFFFFFFFFFFFFF,p6=0xFFFFFFFFFFFFFFFF,p7=0xFFFFFFFFFFFFFFFF,p8=0xFFFFFFFFFFFFFFFF,p9=0xFFFFFFFFFFFFFFFF,p10=0xFFFFFFFFFFFFFFFF){ if((dispid =GetDispID(obj,name))!=0){ params =CreateParam(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) pvRes =Invoke(obj,dispid,2,params) FreeParam(params) return vFree(pvRes,0) } } pp(obj,name,p1=0xFFFFFFFFFFFFFFFF,p2=0xFFFFFFFFFFFFFFFF,p3=0xFFFFFFFFFFFFFFFF,p4=0xFFFFFFFFFFFFFFFF,p5=0xFFFFFFFFFFFFFFFF,p6=0xFFFFFFFFFFFFFFFF,p7=0xFFFFFFFFFFFFFFFF,p8=0xFFFFFFFFFFFFFFFF,p9=0xFFFFFFFFFFFFFFFF,p10=0xFFFFFFFFFFFFFFFF){ if((dispid =GetDispID(obj,name))!=0){ params =CreateParam(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) ;rgdispidNamedArgsのセット namedArgs =Malloc(4) NumPut(namedArgs,params+4) NumPut(0xFFFFFFFD,namedArgs+0) NumPut(1,params+12) pvRes =Invoke(obj,dispid,4,params) FreeParam(params) return vFree(pvRes) } } /* ********************************** イベントシンク用コールバック関数 ********************************** / GuidIsEqual(guid1,guid2){ return DllCall("MSVCRT.dll¥memcmp","UInt",guid1,"UInt",guid2,"UInt",16)=0 } EVENTSINK_QueryInterface(pEv,iid,ppv){ global if(GuidIsEqual(iid,NumGet(pEv+8))||GuidIsEqual(iid,IID_IDispatch)||GuidIsEqual(iid,IID_IUnknown)){ NumPut(pEv,ppv+0) DllCall(M(pEv,1),"UInt",pEv) return 0 } NumPut(0,ppv+0) return 0x80004002 } EVENTSINK_AddRef(pEv){ cRef =NumGet(pEv+4) cRef++ NumPut(cRef,pEv+4) return cRef } EVENTSINK_Release(pEv){ cRef =NumGet(pEv+4) cRef-- NumPut(cRef,pEv+4) if(cRef==0){ EVENTSINK_Destructor(pEv) } return cRef } EVENTSINK_GetTypeInfoCount(pEv,pct){ NumPut(0,pct+0) return 0 } EVENTSINK_GetTypeInfo(pEv,info,lcid,pInfo){ return 0x8002000B;DISP_E_BADINDEX } EVENTSINK_GetIDsOfNames(pEv,riid,szNames,cNames,lcid,pDispID){ return 0x80020006;DISP_E_UNKNOWNNAME } EVENTSINK_Invoke(pEv,dispid,riid,lcid,wFlags,params,pvRes,exinf,argerr){ pTypeInfo =NumGet(pEv+24) ;GetNames hr =DllCall(M(pTypeInfo,7),"UInt",pTypeInfo, "UInt",dispid, "UIntP",bstr, "UInt",1, "UIntP",count) if(hr!=0){ return 0 } wc2mb_ref(bstr,ev) cb =GetOleEventCallback(NumGet(pEv+12),ev) if(cb){ DllCall(cb,"UInt",NumGet(pEv+28), "UInt",params, "UInt",pvRes) } } EVENTSINK_Constructor(){ static vtEventSink if(!vtEventSink){ vtEventSink =Malloc(28) NumPut(RegisterCallback("EVENTSINK_QueryInterface"),vtEventSink+0) NumPut(RegisterCallback("EVENTSINK_AddRef"),vtEventSink+4) NumPut(RegisterCallback("EVENTSINK_Release"),vtEventSink+8) NumPut(RegisterCallback("EVENTSINK_GetTypeInfoCount"),vtEventSink+12) NumPut(RegisterCallback("EVENTSINK_GetTypeInfo"),vtEventSink+16) NumPut(RegisterCallback("EVENTSINK_GetIDsOfNames"),vtEventSink+20) NumPut(RegisterCallback("EVENTSINK_Invoke"),vtEventSink+24) } pEv =Malloc(32) NumPut(vtEventSink,pEv+0) return pEv } EVENTSINK_Destructor(pEv){ Release(NumGet(pEv+28)) Free(pEv) } /* ********************************** コネクト用のインターフェイスIDを検索 ********************************** / find_iid(ByRef obj,ByRef itf,ByRef iid,ByRef refPTypeInfo=0xFFFFFFFFFFFFFFFF){ global LOCALE_USER_DEFAULT ;GetTypeInfo hr =DllCall(M(disp,4),"UInt",obj, "UInt",0, "UInt",LOCALE_USER_DEFAULT, "UIntP",pTypeInfo) if(hr!=0){ return hr } ;GetContainingTypeLib hr =DllCall(M(pTypeInfo,18),"UInt",pTypeInfo, "UIntP",pTypeLib, "UIntP",index) Release(pTypeInfo) if(hr!=0){ return hr } if(!itf){ ;GetTypeInfoOfGuid hr =DllCall(M(pTypeLib,5),"UInt",pTypeLib, "UIntP",iid, "UIntP",refPTypeInfo) Release(pTypeLib) return hr } count =DllCall(M(pTypeLib,3),"UInt",pTypeLib);GetTypeInfoCount found =0 index =0 Loop,%count%{ hr =DllCall(M(pTypeLib,4),"UInt",pTypeLib, "UInt",index, "UIntP",pTypeInfo);GetTypeInfo if(hr!=0){ break } hr =DllCall(M(pTypeInfo,3),"UInt",pTypeInfo, "UIntP",pTypeAttr);GetTypeAttr if(hr!=0){ Release(pTypeInfo) break } if(NumGet(pTypeAttr+40)==5){;typekind==TKIND_COCLASS cTypes =NumGet(pTypeAttr+48,"UShort");cImplTypes type =0 Loop,%cTypes%{ hr =DllCall(M(pTypeInfo,8),"UInt",pTypeInfo, "UInt",type, "UIntP",RefType);GetRefTypeOfImplType if(hr!=0){ break } hr =DllCall(M(pTypeInfo,14),"UInt",pTypeInfo, "UInt",RefType, "UIntP",pImplTypeInfo);GetRefTypeInfo if(hr!=0){ break } ;GetDocumentation hr =DllCall(M(pImplTypeInfo,12),"UInt",pImplTypeInfo, "Int",-1, "UIntP",bstr, "UInt",0, "UInt",0, "UInt",0) if(hr!=0){ Release(pImplTypeInfo) break } wc2mb_ref(bstr,str) if(str==itf){ ;GetTypeAttr if(DllCall(M(pImplTypeInfo,3),"UInt",pImplTypeInfo, "UIntP",pImplTypeAttr)=0){ found =1 iid =Malloc(16) DllCall("kernel32.dll¥RtlMoveMemory", "UInt",iid, "UInt",pImplTypeAttr, "UInt",16) if(refPTypeInfo!=0xFFFFFFFFFFFFFFFF){ refPTypeInfo =pImplTypeInfo AddRef(pImplTypeInfo) } ;ReleaseTypeAttr DllCall(M(pImplTypeInfo,3),"UInt",pImplTypeInfo, "UInt",pImplTypeAttr) } } Release(pImplTypeInfo) if(found||(hr!=0)){ break } type++ } } hr =DllCall(M(pTypeInfo,3),"UInt",pTypeInfo, "UInt",pTypeAttr);ReleaseTypeAttr Release(pTypeInfo) if(found||(hr!=0)){ break } index++ } Release(pTypeLib) if(!found){ return 0x80004002 }else{ return hr } } find_default_source(ByRef obj,ByRef iid,ByRef refPTypeInfo){ global IID_IProvideClassInfo;,IID_IProvideClassInfo2 /* pProvideClassInfo2 =QueryInterface(obj,IID_IProvideClassInfo2) if(ErrorLevel________==0){ ;GetGUID hr =DllCall(M(pProvideClassInfo2,4),"UInt",pProvideClassInfo2, "UInt",1, "UIntP",iid) Release(pProvideClassInfo2) return find_iid(obj,"",iid,refPTypeInfo) } / pProvideClassInfo =QueryInterface(obj,IID_IProvideClassInfo) if(ErrorLevel!=0){ return ErrorLevel } ;GetClassInfo hr =DllCall(M(pProvideClassInfo,3),"UInt",pProvideClassInfo, "UIntP",pTypeInfo) Release(pProvideClassInfo) if(hr!=0){ return hr } ;GetTypeAttr hr =DllCall(M(pTypeInfo,3),"UInt",pTypeInfo, "UIntP",pTypeAttr) if(hr!=0){ Release(pTypeInfo) return hr } cTypes =NumGet(pTypeAttr+48,"UShort");cImplTypes type =0 Loop,%cTypes%{ hr =DllCall(M(pTypeInfo,9),"UInt",pTypeInfo, "UInt",type, "UIntP",iFlags);GetImplTypeFlags if(hr!=0){ continue } if((iFlags 0x3)=0x3){;((iFlags IMPLTYPEFLAG_FDEFAULT) (iFlags IMPLTYPEFLAG_FSOURCE)) hr =DllCall(M(pTypeInfo,8),"UInt",pTypeInfo, "UInt",type, "UIntP",RefType);GetRefTypeOfImplType if(hr!=0){ continue } hr =DllCall(M(pTypeInfo,14),"UInt",pTypeInfo, "UInt",RefType, "UIntP",refPTypeInfo);GetRefTypeInfo if(hr!=0){ break } } type++ } DllCall(M(pTypeInfo,3),"UInt",pTypeInfo, "UInt",pTypeAttr);ReleaseTypeAttr Release(pTypeInfo) if(!refPTypeInfo){ if(hr==0){ return 0x8000FFFF }else{ return hr } } if(DllCall(M(refPTypeInfo,3),"UInt",refPTypeInfo, "UIntP",pTypeAttr)=0){;GetTypeAttr iid =Malloc(16) DllCall("kernel32.dll¥RtlMoveMemory", "UInt",iid, "UInt",pTypeAttr, "UInt",16) DllCall(M(refPTypeInfo,3),"UInt",refPTypeInfo, "UInt",pTypeAttr);ReleaseTypeAttr }else{ Release(refPTypeInfo) refPTypeInfo ="" } return hr } EntryOleEventPrefix(ByRef prefix){ global static OleEventCount=0 if(OleEventID_%prefix%){ return OleEventID_%prefix% }else{ OleEventID_%prefix% =OleEventCount OleEventPrefix_%OleEventCount% =prefix return OleEventCount++ } } GetOleEventCallback(id,ByRef evt){ global local prefix,cb prefix =OleEventPrefix_%id% if(prefix){ if(OleEventCallback_%prefix%%evt%){ return OleEventCallback_%prefix%%evt% } cb =RegisterCallback(prefix . evt) if(cb){ OleEventCallback_%prefix%%evt% =cb return cb } } } ConnectObject(obj,prefix,itf=0xFFFFFFFFFFFFFFFF){ global IID_IConnectionPointContainer if(itf==0xFFFFFFFFFFFFFFFF){ hr =find_default_source(obj,iid,pTypeInfo) }else{ hr =find_iid(obj,itf,iid,pTypeInfo) } if(hr!=0){ ErrorLevel =hr return 0 } pContainer =QueryInterface(obj,IID_IConnectionPointContainer) if(ErrorLevel!=0){ Release(pTypeInfo) return 0 } ;FindConnectionPoint hr =DllCall(M(pContainer,4),"UInt",pContainer, "UInt",iid, "UIntP",pConnectionPoint) Release(pContainer) if(hr!=0){ Release(pTypeInfo) return 0 } pIEV =EVENTSINK_Constructor() NumPut(iid,pIEV+8) ;Advise hr =DllCall(M(pConnectionPoint,5),"UInt",pConnectionPoint, "UInt",pIEV, "UIntP",dwCookie) if(hr!=0){ return 0 } AddRef(obj) evid =EntryOleEventPrefix(prefix) NumPut(evid,pIEV+12) NumPut(dwCookie,pIEV+16) NumPut(pConnectionPoint,pIEV+20) NumPut(pTypeInfo,pIEV+24) NumPut(obj,pIEV+28) } evArgc(ByRef para){ return NumGet(para+8) } evArgv(ByRef para,idx){ num =NumGet(para+8) if(idx num){ return fromVariant(NumGet(para+0)+(num-1-idx)*16) } } evReturn(ByRef res,value){ toVariant(value,res) } /* ********************************** ディスパッチオブジェクト作成 ********************************** / DISPATCH_QueryInterface(ptr,iid,ppv){ global if(GuidIsEqual(iid,IID_IDispatch)||GuidIsEqual(iid,IID_IUnknown)){ NumPut(ptr,ppv+0) DllCall(M(ptr,1),"UInt",ptr) return 0 }else{ NumPut(0,ppv+0) return 0x80004002 } } DISPATCH_AddRef(ptr){ cRef =NumGet(ptr+4) cRef++ NumPut(cRef,ptr+4) return cRef } DISPATCH_Release(ptr){ cRef =NumGet(ptr+4) cRef-- NumPut(cRef,ptr+4) if(cRef==0){ Free(ptr) } return cRef } DISPATCH_GetTypeInfoCount(ptr,pct){ NumPut(0,pct+0) return 0 } DISPATCH_GetTypeInfo(ptr,info,lcid,pInfo){ return 0x8002000B;DISP_E_BADINDEX } DISPATCH_GetIDsOfNames(ptr,riid,pszNames,cNames,lcid,pDispID){ wc2mb_ref(NumGet(pszNames+0),name) hr =GetOleMethodCallback(NumGet(ptr+12),name,cb) NumPut(cb,pDispID+0) return hr } DISPATCH_Invoke(ptr,dispid,riid,lcid,wFlags,params,pvRes,exinf,argerr){ DllCall(dispid,"UInt",ptr, "UInt",params, "UInt",pvRes, "UInt",wFlags) return 0 } EntryOleMethodsPrefix(ByRef prefix,ByRef id){ global static OleMethodsCount=0 if(OleMethodsID_%prefix%){ id =OleMethodsID_%prefix% }else{ OleMethodsID_%prefix% =OleMethodsCount OleMethodsPrefix_%OleMethodsCount% =prefix id =OleMethodsCount++ } } GetOleMethodCallback(id,ByRef name,ByRef cb){ global local prefix cb =0 prefix =OleMethodsPrefix_%id% if(prefix){ if(OleMethodCallback_%prefix%%name%){ cb =OleMethodCallback_%prefix%%name% return 0 }else{ cb =RegisterCallback(prefix . name) if(cb){ OleMethodCallback_%prefix%%name% =cb return 0 }else{ return 0x80020006 } } } } CreateDispatchObject(prefix,exsize=0){ global IID_IDispatch static vtDispatch if(!vtDispatch){ vtDispatch =Malloc(28) NumPut(RegisterCallback("DISPATCH_QueryInterface"),vtDispatch+0) NumPut(RegisterCallback("DISPATCH_AddRef"),vtDispatch+4) NumPut(RegisterCallback("DISPATCH_Release"),vtDispatch+8) NumPut(RegisterCallback("DISPATCH_GetTypeInfoCount"),vtDispatch+12) NumPut(RegisterCallback("DISPATCH_GetTypeInfo"),vtDispatch+16) NumPut(RegisterCallback("DISPATCH_GetIDsOfNames"),vtDispatch+20) NumPut(RegisterCallback("DISPATCH_Invoke"),vtDispatch+24) } EntryOleMethodsPrefix(prefix,id) ptr =Malloc(12+exsize) NumPut(vtDispatch,ptr+0) NumPut(IID_IDispatch,ptr+8) NumPut(id,ptr+12) return ptr }
https://w.atwiki.jp/wiki3_sai/pages/220.html
スクリプト名 :HkSaiSlider(Simple) 用途 :ナビゲータのスライダーをキー入力で操作する 動作環境 : / Win7x64 / SAI 1.1.0 / AutoHotKey Version 1.0.48.05 / Wacom Intuos2 Driver 6.1.2-4 ファイル名:HkSaiSlider.ahk 注意 :misc.ini TabletMouseSimulation = 1 にしないと、 カーソルがSAIウィンドウの上にある時誤動作する。 ページ分離 -- testmen (2009-12-18 07 09 38) 自分で使ってるのでシンプル版として更新 -- testmen (2009-12-23 04 20 19) コメントは1つ上の階層へどうぞ。 ;////////////////////////////////////////////////////////// ; HkSaiSlider(Simple) ; 無保証・再配布・改変自由 ; ; 動作 AutoHotKey 1.0.48.05 ; 推奨 SAI 1.1.0 ; ; 使用法 ; ズームイン(変換) vk1Csc079 ; ズームアウト(無変換) vk1Dsc07B ; このソースの最下部にある、キー設定の部分を変更すれば ; お好みのキーに割り当てられます。 ; ; 注意 ; misc.ini TabletMouseSimulation = 1 にしないと、 ; カーソルがSAIウィンドウの上にある時誤動作する。 ; ; 2009-12-23 ; カイゼン活動 ;////////////////////////////////////////////////////////// #MaxThreads 1 #MaxThreadsPerHotkey 1 #HotkeyInterval 1000 ; This is the default value (milliseconds). #MaxHotkeysPerInterval 50 ; This is the default value. ;////////////////////////////////////////////////////////// ; 設定 /////////////////////////////////////////////////// ;////////////////////////////////////////////////////////// ; ; ナビゲータは独立ウィンドウか ; 設定: ; 0 ... メインウィンドウと統合 ; 1 ... 独立(SAI1.1.0~使用可) ; IsNavigatorIndependent = 1 ; 表示倍率 or 回転角度 ; 設定: ; 0 ... 表示倍率 ; 1 ... 回転角度 ; TargetSlider = 0 ; ;////////////////////////////////////////////////////////// ;設定ここまで //////////////////////////////////////////// ;////////////////////////////////////////////////////////// Target_Wintit=SAI if IsNavigatorIndependent=1 Target_Wintit=ナビゲータ if TargetSlider=0 { Target_Class=sfl_window_class3 if IsNavigatorIndependent=1 Target_Class=sfl_window_class2 Target_Text=表示倍率 } if TargetSlider=1 { Target_Class=sfl_window_class7 if IsNavigatorIndependent=1 Target_Class=sfl_window_class6 Target_Text=回転角度 } ;////////////////////////////////////////////////////////// ;スライダ位置の検出 ControlGetPos, x, y, w, h, %Target_Class%, %Target_Wintit%, %Target_Text% X =x+(w/2) ;////////////////////////////////////////////////////////// SendMode Play return ;////////////////////////////////////////////////////////// ;メイン ; SliderX…スライダのX位置 ; SliderY…スライダのY位置 ; PLM…加算の横方向 ; TClass…ターゲットのクラス ; TWintit…ターゲットのウィンドウタイトル ; Ttext…ターゲットのテキスト NavDrag(SliderX,SliderY,PLM,TClass,TWintit,Ttext) { ;押されたホットキーを保存 PushThishotkey=%A_Thishotkey% ;トラップ(ちょい待機してキー押してなかったらreturn) sleep, 25 if PLM = -1 { GetKeyState, stateZoomOut, %PushThishotkey%,P if stateZoomOut = U return } if PLM = +1 { GetKeyState, stateZoomIn, %PushThishotkey%, P if stateZoomIn = U return } ;入力禁止 BlockInput, MouseMove ;On nowX =SliderX;スライド操作初期位置 minADD =PLM*0.5;増加単位 ;シフトDOWN Send {Shift Down} ;左ボタンDOWN clickLParam = nowX | (SliderY 16) SendMessage, 0x201, 0x0001, ClickLParam ,%TClass%, %TWintit%, %Ttext% ;キーDOWN中の処理 Loop { ;座標加算 nowX = nowX + minADD ;スライド処理 moveLParam = nowX | (SliderY 16) SendMessage, 0x200, 0x0001, moveLParam ,%TClass%, %TWintit%, %Ttext% ;脱出処理 if PLM = -1 { GetKeyState, stateZoomOut, %PushThishotkey%,P if stateZoomOut = U break } if PLM = +1 { GetKeyState, stateZoomIn, %PushThishotkey%, P if stateZoomIn = U break } } ;左ボタンUP outLParam = nowX | (SliderY 16) SendMessage, 0x202, 0x0001, outLParam ,%TClass%, %TWintit%, %Ttext% ;シフトUP Send {Shift Up} ;入力禁止解除 BlockInput, MouseMoveOff return } ;////////////////////////////////////////////////////////// ;////////////////////////////////////////////////////////// ;////////////////////////////////////////////////////////// #IfWinActive, SAI - ahk_class sfl_window_class ;////////////////////////////////////////////////////////// ;ズームアウト(無変換) vk1Dsc07B vk1Dsc07B NavDrag(X,Y,-1,Target_Class,Target_Wintit,Target_Text) ;ズームイン(変換) vk1Csc079 vk1Csc079 NavDrag(X,Y,+1,Target_Class,Target_Wintit,Target_Text) #IfWinActive ;Esc exitapp ; テスト用
https://w.atwiki.jp/talesofdic/pages/1349.html
APW(アクティブパーティウィンドウ) APWはフィールド画面で左下に表示されるウィンドウ。 このウィンドウにはパーティメンバーの内、戦闘メンバーに選ばれている4名が表示され、 フィールド上を移動するとウィンドウの背景も移動する。 また、フィールド画面で何の操作もせずに一定時間経過すると、 ウィンドウ内のキャラクター達が会話を始める。 後のテイルズオブシリーズ作品のスキットの原型となったシステム。 この頃はスキット絵がなかったため、デスティニーキャラは外伝系に出演するまでスキット絵がなかった。
https://w.atwiki.jp/autohotkey_v2/pages/19.html
Table of Contents Introduction Remapping the Keyboard and Mouse Remarks Moving the Mouse Cursor via the Keyboard Remapping via the Registry s "Scancode Map" Related Topics Introduction Limitation AutoHotkey s remapping feature described below is generally not as pure and effective as remapping directly via the Windows registry. For the advantages and disadvantages of each approach, see registry remapping. Remapping the Keyboard and Mouse The syntax for the built-in remapping feature is OriginKey DestinationKey. For example, a script consisting only of the following line would make A behave like B a b The above example does not alter B itself. B would continue to send the "b" keystroke unless you remap it to something else as shown in the following example a b b a The examples above use lowercase, which is recommended for most purposes because it also remaps the corresponding uppercase letters (that is, it will send uppercase when CapsLock is "on" or Shift is held down). By contrast, specifying an uppercase letter on the right side forces uppercase. For example, the following line would produce an uppercase B when you type either "a" or "A" (as long as CapsLock is off) a B Conversely, any modifiers included on the left side but not the right side are automatically released when the key is sent. For example, the following two lines would produce a lowercase "b" when you press either Shift+A or Ctrl+A A b ^a b Mouse Remapping To remap the mouse instead of the keyboard, use the same approach. For example Example Description MButton Shift Makes the middle button behave like Shift. XButton1 LButton Makes the fourth mouse button behave like the left mouse button. RAlt RButton Makes the right Alt behave like the right mouse button. Other Useful Remappings Example Description CapsLock Ctrl Makes CapsLock become Ctrl. To retain the ability to turn CapsLock on and off, add the remapping +CapsLock CapsLock first. This toggles CapsLock on and off when you hold down Shift and press CapsLock. Because both remappings allow additional modifier keys to be held down, the more specific +CapsLock CapsLock remapping must be placed first for it to work. XButton2 ^LButton Makes the fifth mouse button (XButton2) produce a control-click. RAlt AppsKey Makes the right Alt become Menu (which is the key that opens the context menu). RCtrl RWin Makes the right Ctrl become the right Win. Ctrl Alt Makes both Ctrl behave like Alt. However, see alt-tab issues. ^x ^c Makes Ctrl+X produce Ctrl+C. It also makes Ctrl+Alt+X produce Ctrl+Alt+C, etc. RWin Return Disables the right Win by having it simply return. You can try out any of these examples by copying them into a new text file such as "Remap.ahk", then launching the file. See the Key List for a complete list of key and mouse button names. Remarks The #HotIf directive can be used to make selected remappings active only in the windows you specify (or while any given condition is met). For example HotIf WinActive("ahk_class Notepad") a b ; Makes the a key send a b key, but only in Notepad. HotIf ; This puts subsequent remappings and hotkeys in effect for all windows. Remapping a key or button is "complete" in the following respects Holding down a modifier such as Ctrl or Shift while typing the origin key will put that modifier into effect for the destination key. For example, b a would produce Ctrl+A if you press Ctrl+B. CapsLock generally affects remapped keys in the same way as normal keys. The destination key or button is held down for as long as you continue to hold down the origin key. However, some games do not support remapping; in such cases, the keyboard and mouse will behave as though not remapped. Remapped keys will auto-repeat while being held down (except keys remapped to become mouse buttons). Although a remapped key can trigger normal hotkeys, by default it cannot trigger mouse hotkeys or hook hotkeys (use ListHotkeys to discover which hotkeys are "hook"). For example, if the remapping a b is in effect, pressing Ctrl+Alt+A would trigger the ^!b hotkey only if ^!b is not a hook hotkey. If ^!b is a hook hotkey, you can define ^!a as a hotkey if you want Ctrl+Alt+A to perform the same action as Ctrl+Alt+B. For example a b ^!a ^!b ToolTip "You pressed " ThisHotkey Alternatively, #InputLevel can be used to override the default behaviour. For example InputLevel 1 a b InputLevel 0 ^!b ToolTip "You pressed " ThisHotkey If SendMode is used during script startup, it affects all remappings. However, since remapping uses Send "{Blind}" and since the SendPlay mode does not fully support {Blind}, some remappings might not function properly in SendPlay mode (especially Ctrl, Shift, Alt, and Win). To work around this, avoid using SendMode "Play" during script startup when you have remappings; then use the function SendPlay vs. Send in other places throughout the script. Alternatively, you could translate your remappings into hotkeys (as described below) that explicitly call SendEvent vs. Send. If DestinationKey is meant to be {, it has to be escaped, for example, x `{. Otherwise it is interpreted as the opening brace for the hotkey s function. When a script is launched, each remapping is translated into a pair of hotkeys. For example, a script containing a b actually contains the following two hotkeys instead *a { SetKeyDelay -1 ; If the destination key is a mouse button, SetMouseDelay is used instead. Send "{Blind}{b DownR}" ; DownR is like Down except that other Send functions in the script won t assume "b" should stay down during their Send. } *a up { SetKeyDelay -1 ; See note below for why press-duration is not specified with either of these SetKeyDelays. Send "{Blind}{b Up}" } However, the above hotkeys vary under the following circumstances When the source key is the left Ctrl and the destination key is Alt, the line Send "{Blind}{LAlt DownR}" is replaced by Send "{Blind}{LCtrl up}{LAlt DownR}". The same is true if the source is the right Ctrl, except that {RCtrl up} is used. When a keyboard key is being remapped to become a mouse button (e.g. RCtrl RButton), the hotkeys above use SetMouseDelay in place of SetKeyDelay. In addition, the first hotkey above is replaced by the following, which prevents the keyboard s auto-repeat feature from generating repeated mouse clicks RCtrl { SetMouseDelay -1 if not GetKeyState("RButton") ; i.e. the right mouse button isn t down yet. Send "{Blind}{RButton DownR}" } When the source is a custom combination, the wildcard modifier () is omitted to allow the hotkeys to work. Note that SetKeyDelay s second parameter (press duration) is omitted in the hotkeys above. This is because press-duration does not apply to down-only or up-only events such as {b down} and {b up}. However, it does apply to changes in the state of the modifier keys (Shift, Ctrl, Alt, and Win), which affects remappings such as a B or a ^b. Consequently, any press-duration a script puts into effect during script startup will apply to all such remappings. Since remappings are translated into hotkeys as described above, the Suspend function affects them. Similarly, the Hotkey function can disable or modify a remapping. For example, the following two functions would disable the remapping a b. Hotkey "a", "Off" Hotkey "a up", "Off" Alt-tab issues If you remap a key or mouse button to become Alt, that key will probably not be able to alt-tab properly. A possible work-around is to add the hotkey *Tab Send "{Blind}{Tab}" -- but be aware that it will likely interfere with using the real Alt to alt-tab. Therefore, it should be used only when you alt-tab solely by means of remapped keys and/or alt-tab hotkeys. In addition to the keys and mouse buttons on the Key List page, the source key may also be a virtual key (VKnn) or scan code (SCnnn) as described on the special keys page. The same is true for the destination key except that it may optionally specify a scan code after the virtual key. For example, sc01e vk42sc030 is equivalent to a b on most keyboard layouts. To disable a key rather than remapping it, make it a hotkey that simply returns. For example, F1 return would disable F1. The following keys are not supported by the built-in remapping method The mouse wheel (WheelUp/Down/Left/Right). "Pause" as a destination key name (since it matches the name of a built-in function). Instead use vk13 or the corresponding scan code. Curly braces {} as destination keys. Instead use the VK/SC method; e.g. x +sc01A and y +sc01B. Moving the Mouse Cursor via the Keyboard The keyboard can be used to move the mouse cursor as demonstrated by the fully-featured Keyboard-To-Mouse script. Since that script offers smooth cursor movement, acceleration, and other features, it is the recommended approach if you plan to do a lot of mousing with the keyboard. By contrast, the following example is a simpler demonstration #up MouseMove 0, -10, 0, "R" ; Win+UpArrow hotkey = Move cursor upward #Down MouseMove 0, 10, 0, "R" ; Win+DownArrow = Move cursor downward #Left MouseMove -10, 0, 0, "R" ; Win+LeftArrow = Move cursor to the left #Right MouseMove 10, 0, 0, "R" ; Win+RightArrow = Move cursor to the right * #RCtrl ; LeftWin + RightControl = Left-click (hold down Control/Shift to Control-Click or Shift-Click). { SendEvent "{Blind}{LButton down}" KeyWait "RCtrl" ; Prevents keyboard auto-repeat from repeating the mouse click. SendEvent "{Blind}{LButton up}" } * #AppsKey ; LeftWin + AppsKey = Right-click { SendEvent "{Blind}{RButton down}" KeyWait "AppsKey" ; Prevents keyboard auto-repeat from repeating the mouse click. SendEvent "{Blind}{RButton up}" } Remapping via the Registry s "Scancode Map" Advantages Registry remapping is generally more pure and effective than AutoHotkey s remapping. For example, it works in a broader variety of games, it has no known alt-tab issues, and it is capable of firing AutoHotkey s hook hotkeys (whereas AutoHotkey s remapping requires a workaround). If you choose to make the registry entries manually (explained below), absolutely no external software is needed to remap your keyboard. Even if you use KeyTweak to make the registry entries for you, KeyTweak does not need to stay running all the time (unlike AutoHotkey). Disadvantages Registry remapping is relatively permanent a reboot is required to undo the changes or put new ones into effect. Its effect is global it cannot create remappings specific to a particular user, application, or locale. It cannot send keystrokes that are modified by Shift, Ctrl, Alt, or AltGr. For example, it cannot remap a lowercase character to an uppercase one. It supports only the keyboard (AutoHotkey has mouse remapping and some limited joystick remapping). How to Apply Changes to the Registry There are at least two methods to remap keys via the registry Use a program like KeyTweak (freeware) to visually remap your keys. It will change the registry for you. Remap keys manually by creating a .reg file (plain text) and loading it into the registry. This is demonstrated in the archived forums. Related Topics List of keys and mouse buttons GetKeyState Remapping a joystick
https://w.atwiki.jp/autohotkey_v2/pages/15.html
AutoHotkey スクリプトは基本的に、AutoHotkey 専用のカスタム言語で書かれた、プログラムが従う一連の命令です。 この言語は、他のいくつかのスクリプト言語といくつかの類似点がありますが、独自の長所と落とし穴もあります。 このドキュメントでは、言語について説明し、よくある落とし穴を指摘しようとします。 AutoHotkey で利用されるさまざまな概念のより一般的な説明については、概念と規則を参照してください。 目次 一般規約 コメント 式 文字列/テキスト 変数 定数 オペレーター 関数呼び出し 関数呼び出しステートメント オプションのパラメータ オブジェクトの演算子 式ステートメント 制御フロー ステートメント 制御フローとその他のステートメント ループ文 フローを制御しない スクリプトの構造 グローバルコード 機能 #含む その他 動的変数 疑似配列 ラベル 一般規約 名前 変数名と関数名では大文字と小文字が区別されません (たとえば、CurrentDate は currentdate と同じです)。 最大長や使用可能な文字などの詳細については、名前を参照してください。 型付き変数なし 変数には明示的に定義された型がありません。 代わりに、任意の型の値を任意の変数に格納できます (定数と組み込み変数を除く)。 状況に応じて、数値は文字列 (テキスト) に、またはその逆に自動的に変換される場合があります。 宣言はオプションです 関数のページに記載されている場合を除き、変数を宣言する必要はありません。 ただし、値が与えられる前に変数を読み取ろうとすると、エラーと見なされます。 スペースはほとんど無視されます インデント (先頭のスペース) は、読み取り可能なコードを記述するために重要ですが、プログラムでは必要ないため、通常は無視されます。 スペースとタブは通常、行末と式内 (引用符の間を除く) では無視されます。 ただし、次のような場合にはスペースが重要になります。 関数とメソッドの呼び出しでは、関数/メソッド名と (. 連結する場合はスペースが必要です。 あいまいさをなくすために、2 つの演算子の間にスペースが必要になる場合があります。 単一行のコメントは、行の先頭にない場合、先頭にスペースが必要です。 改行は意味があります 通常、改行はステートメントの区切りとして機能し、前の関数呼び出しまたは他のステートメントを終了します。 (ステートメントは、実行される何らかのアクションを表現する言語の最小のスタンドアロン要素です。) これの例外は、行の継続です (以下を参照)。 行の継続 読みやすさと保守性を向上させるために、長い行を小さな行のコレクションに分割できます。 これは前処理によって実現されるため、言語自体の一部ではありません。 次の 3 つの方法があります。 継続プレフィックス 式演算子 (++ と -- を除く) で始まる行は、前の行とマージされます。 行に実際に式が含まれているかどうかに関係なく、行はマージされます。 囲みによる継続 ()、[]、または {} で囲まれた部分式は、ほとんどの場合、自動的に複数の行にまたがることができます。 継続セクション 複数の行は、( で始まり ) で終わるセクションの上の行とマージされます (空白を除いて、両方の記号が行の先頭に表示される必要があります)。 コメント コメントは、プログラムによって無視されるスクリプト内のテキストの一部です。 これらは通常、説明を追加したり、コードの一部を無効にするために使用されます。 スクリプトは、行頭にセミコロンを使用してコメントを付けることができます。 例えば: ; この行全体がコメントです。 行末にコメントを追加することもできます。その場合、セミコロンの左側に少なくとも 1 つのスペースまたはタブが必要です。 例えば: 「メモ帳」を実行します。 これは、関数呼び出しと同じ行のコメントです。 さらに、次の例のように、/ および / 記号を使用して、セクション全体をコメント化できます。 / MsgBox "この行はコメントアウト (無効) されています。" MsgBox "よくある間違い " / "コメントはこれで終わりではありません。" MsgBox "この行はコメントアウトされています。" / MsgBox "この行はコメントアウトされていません。" / これも有効ですが、他のコードは回線を共有できません。 / MsgBox "この行はコメントアウトされていません。" タブとスペースを除いて、/ は行の先頭に表示する必要がありますが、/ は行の先頭または末尾にのみ表示できます。 / を省略しても有効です。省略した場合、ファイルの残りの部分はコメント アウトされます。 スクリプトがファイルから読み取られるときにコメントが除外されるため、パフォーマンスやメモリ使用率に影響を与えることはありません。 式 式は、1 つ以上の値、変数、演算子、および関数呼び出しの組み合わせです。 たとえば、10、1+1、および MyVar は有効な式です。 通常、式は 1 つ以上の値を入力として受け取り、1 つ以上の演算を実行して、結果として値を生成します。 式の値を見つけるプロセスは、評価と呼ばれます。 たとえば、式 1+1 は数値 2 に評価されます。 単純な式を組み合わせて、ますます複雑な式を形成できます。 たとえば、割引/100
https://w.atwiki.jp/autohotkey_v2/pages/20.html
Table of Contents Mouse General Buttons Advanced Buttons Wheel Keyboard General Keys Cursor Control Keys Numpad Keys Function Keys Modifier Keys Multimedia Keys Other Keys Joystick Hand-held Remote Controls Special Keys CapsLock and IME Mouse General Buttons Name Description LButton Primary mouse button. Which physical button this corresponds to depends on system settings; by default it is the left button. RButton Secondary mouse button. Which physical button this corresponds to depends on system settings; by default it is the right button. MButton Middle or wheel mouse button Advanced Buttons Name Description XButton1 4th mouse button. Typically performs the same function as Browser_Back. XButton2 5th mouse button. Typically performs the same function as Browser_Forward. Wheel Name Description WheelDown Turn the wheel downward (toward you). WheelUp Turn the wheel upward (away from you). WheelLeft WheelRight Scroll to the left or right. These can be used as hotkeys with some (but not all) mice which have a second wheel or support tilting the wheel to either side. In some cases, software bundled with the mouse must instead be used to control this feature. Regardless of the particular mouse, Send and Click can be used to scroll horizontally in programs which support it. Keyboard Note The names of the letter and number keys are the same as that single letter or digit. For example b is B and 5 is 5. Although any single character can be used as a key name, its meaning (scan code or virtual keycode) depends on the current keyboard layout. Additionally, some special characters may need to be escaped or enclosed in braces, depending on the context. The letters a-z or A-Z can be used to refer to the corresponding virtual keycodes (usually vk41-vk5A) even if they are not included in the current keyboard layout. General Keys Name Description CapsLock CapsLock (caps lock key) Note Windows IME may interfere with the detection and functionality of CapsLock; see CapsLock and IME for details. Space Space (space bar) Tab Tab (tabulator key) Enter Enter Escape (or Esc) Esc Backspace (or BS) Backspace Cursor Control Keys Name Description ScrollLock ScrollLock (scroll lock key). While Ctrl is held down, ScrollLock produces the key code of CtrlBreak, but can be differentiated from Pause by scan code. Delete (or Del) Del Insert (or Ins) Ins Home Home End End PgUp PgUp (page up key) PgDn PgDn (page down key) Up ↑ (up arrow key) Down ↓ (down arrow key) Left ← (left arrow key) Right → (right arrow key) Numpad Keys Due to system behavior, the following keys separated by a slash are identified differently depending on whether NumLock is ON or OFF. If NumLock is OFF but Shift is pressed, the system temporarily releases Shift and acts as though NumLock is ON. Name Description Numpad0 / NumpadIns 0 / Ins Numpad1 / NumpadEnd 1 / End Numpad2 / NumpadDown 2 / ↓ Numpad3 / NumpadPgDn 3 / PgDn Numpad4 / NumpadLeft 4 / ← Numpad5 / NumpadClear 5 / typically does nothing Numpad6 / NumpadRight 6 / → Numpad7 / NumpadHome 7 / Home Numpad8 / NumpadUp 8 / ↑ Numpad9 / NumpadPgUp 9 / PgUp NumpadDot / NumpadDel . / Del NumLock NumLock (number lock key). While Ctrl is held down, NumLock produces the key code of Pause, so use ^Pause in hotkeys instead of ^NumLock. NumpadDiv / (division) NumpadMult * (multiplication) NumpadAdd + (addition) NumpadSub - (subtraction) NumpadEnter Enter Function Keys Name Description F1 - F24 The 12 or more function keys at the top of most keyboards. Modifier Keys Name Description LWin Left Win. Corresponds to the # hotkey prefix. RWin Right Win. Corresponds to the # hotkey prefix. Note Unlike Ctrl/Alt/Shift, there is no generic/neutral "Win" key because the OS does not support it. However, hotkeys with the # modifier can be triggered by either Win. Control (or Ctrl) Ctrl. As a hotkey (Control ) it fires upon release unless it has the tilde prefix. Corresponds to the ^ hotkey prefix. Alt Alt. As a hotkey (Alt ) it fires upon release unless it has the tilde prefix. Corresponds to the ! hotkey prefix. Shift Shift. As a hotkey (Shift ) it fires upon release unless it has the tilde prefix. Corresponds to the + hotkey prefix. LControl (or LCtrl) Left Ctrl. Corresponds to the ^ hotkey prefix. RControl (or RCtrl) Right Ctrl. Corresponds to the ^ hotkey prefix. LShift Left Shift. Corresponds to the + hotkey prefix. RShift Right Shift. Corresponds to the + hotkey prefix. LAlt Left Alt. Corresponds to the ! hotkey prefix. RAlt Right Alt. Corresponds to the ! hotkey prefix. Note If your keyboard layout has AltGr instead of RAlt, you can probably use it as a hotkey prefix via ^ ! as described here. In addition, LControl RAlt would make AltGr itself into a hotkey. Multimedia Keys The function assigned to each of the keys listed below can be overridden by modifying the Windows registry. This table shows the default function of each key on most versions of Windows. Name Description Browser_Back Back Browser_Forward Forward Browser_Refresh Refresh Browser_Stop Stop Browser_Search Search Browser_Favorites Favorites Browser_Home Homepage Volume_Mute Mute the volume Volume_Down Lower the volume Volume_Up Increase the volume Media_Next Next Track Media_Prev Previous Track Media_Stop Stop Media_Play_Pause Play/Pause Launch_Mail Launch default e-mail program Launch_Media Launch default media player Launch_App1 Launch My Computer Launch_App2 Launch Calculator Other Keys Name Description AppsKey Menu. This is the key that invokes the right-click context menu. PrintScreen PrtSc (print screen key) CtrlBreak Ctrl+Pause or Ctrl+ScrollLock Pause Pause or Ctrl+NumLock. While Ctrl is held down, Pause produces the key code of CtrlBreak and NumLock produces Pause, so use ^CtrlBreak in hotkeys instead of ^Pause. Help Help. This probably doesn t exist on most keyboards. It s usually not the same as F1. Sleep Sleep. Note that the sleep key on some keyboards might not work with this. SCnnn Specify for nnn the scan code of a key. Recognizes unusual keys not mentioned above. See Special Keys for details. VKnn Specify for nn the hexadecimal virtual key code of a key. This rarely-used method also prevents certain types of hotkeys from requiring the keyboard hook. For example, the following hotkey does not use the keyboard hook, but as a side-effect it is triggered by pressing either Home or NumpadHome ^VK24 MsgBox "You pressed Home or NumpadHome while holding down Control." Known limitation VK hotkeys that are forced to use the keyboard hook, such as *VK24 or ~VK24, will fire for only one of the keys, not both (e.g. NumpadHome but not Home). For more information about the VKnn method, see Special Keys. Warning Only Send, GetKeyName, GetKeyVK, GetKeySC and A_MenuMaskKey support combining VKnn and SCnnn. If combined in any other case (or if any other invalid suffix is present), the key is not recognized. For example, vk1Bsc001 raises an error. Joystick Joy1 through Joy32 The buttons of the joystick. To help determine the button numbers for your joystick, use this test script. Note that hotkey prefix symbols such as ^ (control) and + (shift) are not supported (though GetKeyState can be used as a substitute). Also note that the pressing of joystick buttons always "passes through" to the active window if that window is designed to detect the pressing of joystick buttons. Although the following Joystick control names cannot be used as hotkeys, they can be used with GetKeyState JoyX, JoyY, and JoyZ The X (horizontal), Y (vertical), and Z (altitude/depth) axes of the joystick. JoyR The rudder or 4th axis of the joystick. JoyU and JoyV The 5th and 6th axes of the joystick. JoyPOV The point-of-view (hat) control. JoyName The name of the joystick or its driver. JoyButtons The number of buttons supported by the joystick (not always accurate). JoyAxes The number of axes supported by the joystick. JoyInfo Provides a string consisting of zero or more of the following letters to indicate the joystick s capabilities Z (has Z axis), R (has R axis), U (has U axis), V (has V axis), P (has POV control), D (the POV control has a limited number of discrete/distinct settings), C (the POV control is continuous/fine). Example string ZRUVPD Multiple Joysticks If the computer has more than one joystick and you want to use one beyond the first, include the joystick number (max 16) in front of the control name. For example, 2joy1 is the second joystick s first button. Note If you have trouble getting a script to recognize your joystick, one person reported needing to specify a joystick number other than 1 even though only a single joystick was present. It is unclear how this situation arises or whether it is normal, but experimenting with the joystick number in the joystick test script can help determine if this applies to your system. See Also Joystick remapping Methods of sending keystrokes and mouse clicks with a joystick. Joystick-To-Mouse script Using a joystick as a mouse. Hand-held Remote Controls Respond to signals from hand-held remote controls via the WinLIRC client script. Special Keys If your keyboard or mouse has a key not listed above, you might still be able to make it a hotkey by using the following steps Ensure that at least one script is running that is using the keyboard hook. You can tell if a script has the keyboard hook by opening its main window and selecting "View- Key history" from the menu bar. Double-click that script s tray icon to open its main window. Press one of the "mystery keys" on your keyboard. Select the menu item "View- Key history" Scroll down to the bottom of the page. Somewhere near the bottom are the key-down and key-up events for your key. NOTE Some keys do not generate events and thus will not be visible here. If this is the case, you cannot directly make that particular key a hotkey because your keyboard driver or hardware handles it at a level too low for AutoHotkey to access. For possible solutions, see further below. If your key is detectable, make a note of the 3-digit hexadecimal value in the second column of the list (e.g. 159). To define this key as a hotkey, follow this example SC159 MsgBox ThisHotkey " was pressed." ; Replace 159 with your key s value. Also see ThisHotkey. Reverse direction To remap some other key to become a "mystery key", follow this example ; Replace 159 with the value discovered above. Replace FF (if needed) with the ; key s virtual key, which can be discovered in the first column of the Key History screen. c Send "{vkFFsc159}" ; See Send {vkXXscYYY} for more details. Alternate solutions If your key or mouse button is not detectable by the Key History screen, one of the following might help Reconfigure the software that came with your mouse or keyboard (sometimes accessible in the Control Panel or Start Menu) to have the "mystery key" send some other keystroke. Such a keystroke can then be defined as a hotkey in a script. For example, if you configure a mystery key to send Ctrl+F1, you can then indirectly make that key as a hotkey by using ^F1 in a script. Try AHKHID. You can also try searching the forum for a keywords like RawInput*, USB HID or AHKHID. The following is a last resort and generally should be attempted only in desperation. This is because the chance of success is low and it may cause unwanted side-effects that are difficult to undo Disable or remove any extra software that came with your keyboard or mouse or change its driver to a more standard one such as the one built into the OS. This assumes there is such a driver for your particular keyboard or mouse and that you can live without the features provided by its custom driver and software. CapsLock and IME Some configurations of Windows IME (such as Japanese input with English keyboard) use CapsLock to toggle between modes. In such cases, CapsLock is suppressed by the IME and cannot be detected by AutoHotkey. However, the Alt+CapsLock, Ctrl+CapsLock and Shift+CapsLock shortcuts can be disabled with a workaround. Specifically, send a key-up to modify the state of the IME, but prevent any other effects by signalling the keyboard hook to suppress the event. The following function can be used for this purpose ; The keyboard hook must be installed. InstallKeybdHook SendSuppressedKeyUp(key) { DllCall("keybd_event" , "char", GetKeyVK(key) , "char", GetKeySC(key) , "uint", KEYEVENTF_KEYUP = 0x2 , "uptr", KEY_BLOCK_THIS = 0xFFC3D450) } After copying the function into a script or saving it as SendSuppressedKeyUp.ahk in a Lib folder and adding #Include to the script, it can be used as follows ; Disable Alt+key shortcuts for the IME. ~LAlt SendSuppressedKeyUp "LAlt" ; Test hotkey !CapsLock MsgBox A_ThisHotkey ; Remap CapsLock to LCtrl in a way compatible with IME. CapsLock { Send "{Blind}{LCtrl DownR}" SendSuppressedKeyUp "LCtrl" } CapsLock up { Send "{Blind}{LCtrl Up}" }